Merge upstream changes.

This commit is contained in:
iamshnoo
2020-08-25 18:13:17 +05:30
128 changed files with 4478 additions and 1579 deletions
+2 -2
View File
@@ -18,7 +18,7 @@ jobs:
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF'
Python:
python.version: '3.7'
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DPYTHON_EXECUTABLE=/opt/hostedtoolcache/Python/3.7.7/x64/bin/python3 -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF'
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF'
Julia:
julia.version: '1.3.0'
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_GO_BINDINGS=OFF -DJULIA_EXECUTABLE=/opt/julia-1.3.0/bin/julia'
@@ -42,7 +42,7 @@ jobs:
python.version: '2.7'
Python:
python.version: '3.7'
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF'
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF'
Julia:
python.version: '2.7'
julia.version: '1.3.0'
+2 -5
View File
@@ -22,12 +22,9 @@ steps:
echo "##vso[task.setvariable variable=BOOST_ROOT]"$BOOST_ROOT
sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost1.70-dev libarmadillo-dev xz-utils
sudo apt-get install -y --allow-unauthenticated python3-pip python3-numpy
sudo /opt/hostedtoolcache/Python/3.7.7/x64/bin/python3 -m pip install "Cython>0.24"
sudo /opt/hostedtoolcache/Python/3.7.7/x64/bin/python3 -m pip install --upgrade --ignore-installed setuptools
sudo /opt/hostedtoolcache/Python/3.7.7/x64/bin/python3 -m pip install pandas
/usr/bin/python3 -m pip install --upgrade pip
/usr/bin/python3 -m pip install --upgrade --ignore-installed setuptools cython pandas
if [ 'a$(julia.version)' != 'a' ]; then
wget https://julialang-s3.julialang.org/bin/linux/x64/1.3/julia-1.3.0-linux-x86_64.tar.gz
+9 -1
View File
@@ -16,7 +16,6 @@ option(BUILD_CLI_EXECUTABLES "Build command-line executables." ON)
option(DISABLE_DOWNLOADS "Disable downloads of dependencies during build." OFF)
option(DOWNLOAD_ENSMALLEN "If ensmallen is not found, download it." ON)
option(DOWNLOAD_STB_IMAGE "Download stb_image for image loading." ON)
option(BUILD_PYTHON_BINDINGS "Build Python bindings." ON)
option(BUILD_GO_SHLIB "Build Go shared library." OFF)
if (WIN32)
@@ -30,6 +29,15 @@ else ()
"Compile shared libraries (if OFF, static libraries are compiled)." ON)
endif()
# Detect whether the user passed BUILD_PYTHON_BINDINGS in order to determine if
# we should fail if Python isn't found.
if (BUILD_PYTHON_BINDINGS)
set(FORCE_BUILD_PYTHON_BINDINGS ON)
else()
set(FORCE_BUILD_PYTHON_BINDINGS OFF)
endif()
option(BUILD_PYTHON_BINDINGS "Build Python bindings." OFF)
# Detect whether the user passed BUILD_JULIA_BINDINGS in order to determine if
# we should fail if Julia isn't found.
if (BUILD_JULIA_BINDINGS)
+9
View File
@@ -1,5 +1,10 @@
### mlpack ?.?.?
###### ????-??-??
* Force CMake to show error when it didn't find Python/modules (#2568).
* Refactor `ProgramInfo()` to separate out all the different
information (#2558).
* Added Soft Actor-Critic to RL methods (#2487).
* Added Categorical DQN to q_networks (#2454).
@@ -20,6 +25,10 @@
version of linear regression where the regularization parameter is
automatically tuned (#2030).
* Fix incremental training of logistic regression models (#2560).
* Change default configuration of `BUILD_PYTHON_BINDINGS` to `OFF` (#2575).
### mlpack 3.3.2
###### 2020-06-18
* Added Noisy DQN to q_networks (#2446).
+197 -56
View File
@@ -19,7 +19,7 @@ The document is split into several sections:
- @ref bindings_intro
- @ref bindings_code
- @ref bindings_general
- @ref bindings_general_program_info
- @ref bindings_general_program_doc
- @ref bindings_general_define_params
- @ref bindings_general_functions
- @ref bindings_general_more
@@ -128,12 +128,18 @@ using namespace std;
// being used. Note that the macros must have + on either side of them. We
// provide some extra references with the "SEE_ALSO()" macro, which is used to
// generate documentation for the website.
PROGRAM_INFO("Mean Shift Clustering",
// Short description.
// Program Name.
BINDING_NAME("Mean Shift Clustering");
// Short description.
BINDING_SHORT_DESC(
"A fast implementation of mean-shift clustering using dual-tree range "
"search. Given a dataset, this uses the mean shift algorithm to produce "
"and return a clustering of the data.",
// Long description.
"and return a clustering of the data.");
// Long description.
BINDING_LONG_DESC(
"This program performs mean shift clustering on the given dataset, storing "
"the learned cluster assignments either as a column of labels in the input "
"dataset or separately."
@@ -147,22 +153,26 @@ PROGRAM_INFO("Mean Shift Clustering",
"\n\n"
"The output labels may be saved with the " + PRINT_PARAM_STRING("output") +
" output parameter and the centroids of each cluster may be saved with the"
" " + PRINT_PARAM_STRING("centroid") + " output parameter."
"\n\n"
" " + PRINT_PARAM_STRING("centroid") + " output parameter.");
// Example.
BINDING_EXAMPLE(
"For example, to run mean shift clustering on the dataset " +
PRINT_DATASET("data") + " and store the centroids to " +
PRINT_DATASET("centroids") + ", the following command may be used: "
"\n\n" +
PRINT_CALL("mean_shift", "input", "data", "centroid", "centroids"),
SEE_ALSO("@kmeans", "#kmeans"),
SEE_ALSO("@dbscan", "#dbscan"),
SEE_ALSO("Mean shift on Wikipedia",
"https://en.wikipedia.org/wiki/Mean_shift"),
SEE_ALSO("Mean Shift, Mode Seeking, and Clustering (pdf)",
PRINT_CALL("mean_shift", "input", "data", "centroid", "centroids"));
// See also...
BINDING_SEE_ALSO("@kmeans", "#kmeans");
BINDING_SEE_ALSO("@dbscan", "#dbscan");
BINDING_SEE_ALSO("Mean shift on Wikipedia",
"https://en.wikipedia.org/wiki/Mean_shift");
BINDING_SEE_ALSO("Mean Shift, Mode Seeking, and Clustering (pdf)",
"http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.510.1222"
"&rep=rep1&type=pdf"),
SEE_ALSO("mlpack::mean_shift::MeanShift C++ class documentation",
"@doxygen/classmlpack_1_1meanshift_1_1MeanShift.html"));
"&rep=rep1&type=pdf");
BINDING_SEE_ALSO("mlpack::mean_shift::MeanShift C++ class documentation",
"@doxygen/classmlpack_1_1meanshift_1_1MeanShift.html");
// Define parameters for the executable.
@@ -228,9 +238,10 @@ void mlpackMain()
@endcode
We can see that we have defined the basic program information in the
@c PROGRAM_INFO() macro. This is, for instance, what is displayed to describe
the binding if the user passed the <tt>\--help</tt> option for a
command-line program.
@c BINDING_NAME(), @c BINDING_SHORT_DESC(), @c BINDING_LONG_DESC(),
@c BINDING_EXAMPLE() and @c BINDING_SEE_ALSO() macros. This is, for instance,
what is displayed to describe the binding if the user passed the
<tt>\--help</tt> option for a command-line program.
Then, we define five parameters, three input and two output, that define the
data and options that the mean shift clustering will function on. These
@@ -247,10 +258,12 @@ whether the parameter is input or output. Some examples:
Note that each of these macros may have slightly different syntax. See the
links above for further documentation.
In order to write a new binding, then, you simply must write a @c PROGRAM_INFO()
definition of the program with some docuentation, define the input and output
parameters as @c PARAM macros, and then write an @c mlpackMain() function that
actually performs the functionality of the binding. Inside of @c mlpackMain():
In order to write a new binding, then, you simply must write @c BINDING_NAME(),
@c BINDING_SHORT_DESC(), @c BINDING_LONG_DESC(), @c BINDING_EXAMPLE() and
@c BINDING_SEE_ALSO() definitions of the program with some docuentation, define
the input and output parameters as @c PARAM macros, and then write an
@c mlpackMain() function that actually performs the functionality of the binding.
Inside of @c mlpackMain():
- All input parameters are accessible through @c IO::GetParam<type>("name").
- All output parameters should be set by the end of the function with the
@@ -278,15 +291,27 @@ relatively clear how one could use the @c IO functionality along with CMake to
add a binding for a new mlpack machine learning method. If it is not clear,
then the examples in the following sections should clarify.
@subsection bindings_general_program_info Documenting a program with PROGRAM_INFO()
@subsection bindings_general_program_doc Documenting a program with
@c BINDING_NAME(), @c BINDING_SHORT_DESC(), @c BINDING_LONG_DESC(),
@c BINDING_EXAMPLE() and @c BINDING_SEE_ALSO().
Any mlpack program should be documented with the @c PROGRAM_INFO() macro, which
is available from the @c <mlpack/core/util/mlpack_main.hpp> header. The macro
is of the form
Any mlpack program should be documented with the @c BINDING_NAME(),
@c BINDING_SHORT_DESC(), @c BINDING_LONG_DESC() , @c BINDING_EXAMPLE() and
@c BINDING_SEE_ALSO() macros, which is available from the
@c <mlpack/core/util/mlpack_main.hpp> header. The macros
are of the form
@code
PROGRAM_INFO("program name", "short documentation", "long documentation",
SEE_ALSO("link", "description"), ...)
BINDING_NAME("program name");
BINDING_SHORT_DESC("This is a short, two-sentence description of what the program does.");
BINDING_LONG_DESC("This is a long description of what the program does."
" It might be many lines long and have lots of details about different options.");
BINDING_EXAMPLE("This contains one example for this particular binding.\n" +
PROGRAM_CALL(...));
BINDING_EXAMPLE("This contains another example for this particular binding.\n" +
PROGRAM_CALL(...));
// There could be many of these "see alsos".
BINDING_SEE_ALSO("https://en.wikipedia.org/wiki/Machine_learning");
@endcode
The short documentation should be two sentences indicating what the program
@@ -368,6 +393,14 @@ Command-line program output (snippet):
Python binding output (snippet):
The parameter 'shuffle', if set, will shuffle the data before learning.
Julia binding output (snippet):
The parameter `shuffle`, if set, will shuffle the data before learning.
Go binding output (snippet):
The parameter "Shuffle", if set, will shuffle the data before learning.
@endcode
@code
@@ -383,6 +416,14 @@ Command-line program output (snippet):
Python binding output (snippet):
The output matrix can be saved with the 'output' output parameter.
Julia binding output (snippet):
The output matrix can be saved with the `output` output parameter.
Go binding output (snippet):
The output matrix can be saved with the "output" output parameter.
@endcode
@code
@@ -408,12 +449,38 @@ Python binding output (snippet):
>>> output = program(input=x)
>>> model = output['output_model']
Julia binding output (snippet):
For example, to train a model on the dataset `x` and save the output model to
`model`, the following command can be used:
julia> model = program(input=x)
Go binding output (snippet):
For example, to train a model on the dataset "x" and save the output model to
"model", the following command can be used:
// Initialize optional parameters for Program().
param := mlpack.ProgramOptions()
param.Input = x
model := mlpack.Program(param)
@endcode
@code
Input C++ (full program, 'random_numbers_main.cpp'):
PROGRAM_INFO("Random Numbers", "This program generates random numbers with a "
// Program Name.
BINDING_NAME("Random Numbers");
// Short description.
BINDING_SHORT_DESC("An implementation of Random Numbers");
// Long description.
BINDING_LONG_DESC(
"This program generates random numbers with a "
"variety of nonsensical techniques and example parameters. The input "
"dataset, which will be ignored, can be specified with the " +
PRINT_PARAM_STRING("input") + " parameter. If you would like to subtract"
@@ -425,8 +492,10 @@ Input C++ (full program, 'random_numbers_main.cpp'):
"The output random numbers can be saved with the " +
PRINT_PARAM_STRING("output") + " output parameter. In addition, a "
"randomly generated linear regression model can be saved with the " +
PRINT_PARAM_STRING("output_model") + " output parameter."
"\n\n"
PRINT_PARAM_STRING("output_model") + " output parameter.");
// Example.
BINDING_EXAMPLE(
"For example, to generate 100 random numbers with 3 subtracted from them "
"and save the output to " + PRINT_DATASET("rand") + " and the random "
"model to " + PRINT_MODEL("rand_lr") + ", use the following "
@@ -479,17 +548,66 @@ Python binding output:
>>> output = random_numbers(num_values=100, subtract=3)
>>> rand = output['output']
>>> rand_lr = output['output_model']
Julia binding output:
Random Numbers
This program generates random numbers with a variety of nonsensical
techniques and example parameters. The input dataset, which will be
ignored, can be specified with the `input` parameter. If you would like to
subtract values from each number, specify the `subtract` parameter. The
number of random numbers to generate is specified with the `num_values`
parameter.
The output random numbers can be saved with the `output` output parameter.
In addition, a randomly generated linear regression model can be saved with
the `output_model` output parameter.
For example, to generate 100 random numbers with 3 subtracted from them and
save the output to `rand` and the random model to `rand_lr`, use the
following command:
```julia
julia> rand, rand_lr = random_numbers(num_values=100, subtract=3)
```
Go binding output:
Random Numbers
This program generates random numbers with a variety of nonsensical
techniques and example parameters. The input dataset, which will be
ignored, can be specified with the "Input" parameter. If you would like to
subtract values from each number, specify the "Subtract" parameter. The
number of random numbers to generate is specified with the "NumValues"
parameter.
The output random numbers can be saved with the "output" output parameter.
In addition, a randomly generated linear regression model can be saved with
the "outputModel" output parameter.
For example, to generate 100 random numbers with 3 subtracted from them and
save the output to "rand" and the random model to "randLr", use the
following command:
// Initialize optional parameters for RandomNumbers().
param := mlpack.RandomNumbersOptions()
param.NumValues = 100
param.Subtract=3
rand, randLr := mlpack.RandomNumbers(param)
@endcode
@subsection bindings_general_define_params Defining parameters for a program
There exist several macros that can be used after a @c PROGRAM_INFO() definition
to define the parameters that can be specified for a given mlpack program.
These macros all have the same general definition: the name of the macro
specifies the type of the parameter, whether or not the parameter is required,
and whether the parameter is an input or output parameter. Then as arguments to
the macro, the name, description, and sometimes the single-character alias and
the default value of the parameter.
There exist several macros that can be used after a @c BINDING_LONG_DESC() and
@c BINDING_EXAMPLE() definition to define the parameters that can be specified
for a given mlpack program. These macros all have the same general definition:
the name of the macro specifies the type of the parameter, whether or not the
parameter is required, and whether the parameter is an input or output parameter.
Then as arguments to the macros, the name, description, and sometimes the
single-character alias and the default value of the parameter.
To give a flavor of how these definitions look, the definition
@@ -620,10 +738,10 @@ Python interface to the user.
mlpack's @c IO module provides a unified abstract interface for getting input
from and providing output to users without needing to consider the language
(command-line, Python, MATLAB, etc.) that the user is running the program from.
This means that after the @c PROGRAM_INFO() macro and the @c PARAM_*() macros
have been defined, a language-agnostic @c mlpackMain() function can be written.
This function then can perform the actual computation that the entire program is
meant to.
This means that after the @c BINDING_LONG_DESC() and @c BINDING_EXAMPLE() macros
and the @c PARAM_*() macros have been defined, a language-agnostic
@c mlpackMain() function can be written. This function then can perform the
actual computation that the entire program is meant to.
Inside of an @c mlpackMain() function, the @c mlpack::IO module can be used to
access input parameters and set output parameters. There are two main functions
@@ -703,7 +821,8 @@ could be created for the "random_numbers" program from earlier sections.
@code
#include <mlpack/core/util/mlpack_main.hpp>
// The PROGRAM_INFO() and PARAM_*() definitions should go here:
// BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC() , BINDING_EXAMPLE(),
// BINDING_SEE_ALSO() and PARAM_*() definitions should go here:
// ...
using namespace mlpack;
@@ -759,23 +878,43 @@ This section describes the internal functionality of the IO module and the
associated macros. If you are only interested in writing mlpack programs, this
section is probably not worth reading.
There are four main components involved with mlpack bindings:
There are eight main components involved with mlpack bindings:
- the IO module, a singleton class that stores parameter information
- the mlpackMain() function that defines the functionality of the binding
- the PROGRAM_INFO() macro that defines the binding name and documentation
- the BINDING_NAME() macro that defines the binding name
- the BINDING_SHORT_DESC() macro that defines the short description
- the BINDING_LONG_DESC() macro that defines the long description
- (optional) the BINDING_EXAMPLE() macro that defines example usages
- (optional) the BINDING_SEE_ALSO() macro that defines "see also" links
- the PARAM_*() macros that define parameters for the binding
The mlpack::IO module is a singleton class that stores, at runtime, the binding
name, the documentation, and the parameter information and values. In order to
do this, each parameter and the program documentation must make themselves known
to the IO singleton. This is accomplished by having the @c PROGRAM_INFO() and
@c PARAM_*() macros declare global variables that, in their constructors,
register themselves with the IO singleton.
to the IO singleton. This is accomplished by having the @c BINDING_NAME(),
@c BINDING_SHORT_DESC(), @c BINDING_LONG_DESC(), @c BINDING_EXAMPLE(),
@c BINDING_SEE_ALSO() and @c PARAM_*() macros declare global variables that,
in their constructors, register themselves with the IO singleton.
The @c PROGRAM_INFO() macro declares an object of type mlpack::util::ProgramDoc.
The @c ProgramDoc class constructor calls IO::RegisterProgramDoc() in order to
register the given program name and documentation.
The @c BINDING_NAME() macro declares an object of type mlpack::util::ProgramName.
The @c BINDING_SHORT_DESC() macro declares an object of type
mlpack::util::ShortDescription.
The @c BINDING_LONG_DESC() macro declares an object of type
mlpack::util::LongDescription.
The @c BINDING_EXAMPLE() macro declares an object of type mlpack::util::Example.
The @c BINDING_SEE_ALSO() macro declares an object of type
mlpack::util::SeeAlso.
The @c ProgramName class constructor calls IO::RegisterProgramName() in order to
register the given program name.
The @c ShortDescription class constructor calls IO::RegisterShortDescription() in order to
register the given short description.
The @c LongDescription class constructor calls IO::RegisterLongDescription() in order to
register the given long description.
The @c Example class constructor calls IO::RegisterExample() in order to
register the given example.
The @c SeeAlso class constructor calls IO::RegisterSeeAlso() in order to
register the given see-also link.
The @c PARAM_*() macros declare an object that will, in its constructor, call
IO::Add() to register that parameter with the IO singleton. The specific type
@@ -875,7 +1014,8 @@ binding:
- The options defined by @c PARAM_*() macros are of type
mlpack::bindings::cli::CLIOption.
- The parameter and value printing macros for @c PROGRAM_INFO() are set:
- The parameter and value printing macros for @c BINDING_LONG_DESC()
and BINDING_EXAMPLE() are set:
* The @c PRINT_PARAM_STRING() macro is defined as
mlpack::bindings::cli::ParamString().
* The @c PRINT_DATASET() macro is defined as
@@ -1047,9 +1187,10 @@ individually if you like). The file
the name of the program and the @c *_main.cpp file to include correctly, then
the @c mlpack::bindings::python::PrintPYX() function is called by the program.
The @c PrintPYX() function uses the parameters that have been set in the IO
singleton by the @c PROGRAM_INFO() and @c PARAM_*() macros in order to actually
print a fully-working .pyx file that can be compiled. The file has several
sections:
singleton by the @c BINDING_NAME(), @c BINDING_SHORT_DESC(),
@c BINDING_LONG_DESC(), @c BINDING_EXAMPLE(), @c BINDING_SEE_ALSO() and
@c PARAM_*() macros in order to actually print a fully-working .pyx file that
can be compiled. The file has several sections:
- Python imports (numpy/pandas/cython/etc.)
- Cython imports of C++ utility functions and Armadillo functionality
+17 -11
View File
@@ -120,7 +120,8 @@ and debugging output for your mlpack program.
@section simpleio Simple IO Example
Through the mlpack::IO object, command-line parameters can be easily added
with the PROGRAM_INFO, PARAM_INT, PARAM_DOUBLE, PARAM_STRING, and PARAM_FLAG
with the BINDING_NAME, BINDING_SHORT_DESC, BINDING_LONG_DESC, BINDING_EXAMPLE,
BINDING_SEE_ALSO, PARAM_INT, PARAM_DOUBLE, PARAM_STRING, and PARAM_FLAG
macros.
Here is a sample use of those macros, extracted from methods/pca/pca_main.cpp.
@@ -131,23 +132,28 @@ Here is a sample use of those macros, extracted from methods/pca/pca_main.cpp.
#include <mlpack/core/util/io.hpp>
#include <mlpack/core/util/mlpack_main.hpp>
// Document program.
PROGRAM_INFO("Principal Components Analysis",
// Short description.
// Program Name.
BINDING_NAME("Principal Components Analysis");
// Short description.
BINDING_SHORT_DESC(
"An implementation of several strategies for principal components analysis "
"(PCA), a common preprocessing step. Given a dataset and a desired new "
"dimensionality, this can reduce the dimensionality of the data using the "
"linear transformation determined by PCA.",
// Long description.
"linear transformation determined by PCA.");
// Long description.
BINDING_LONG_DESC(
"This program performs principal components analysis on the given dataset "
"using the exact, randomized, randomized block Krylov, or QUIC SVD method. "
"It will transform the data onto its principal components, optionally "
"performing dimensionality reduction by ignoring the principal components "
"with the smallest eigenvalues."
// "See also" section for generated documentation.
SEE_ALSO("Principal component analysis on Wikipedia",
"https://en.wikipedia.org/wiki/Principal_component_analysis"),
SEE_ALSO("mlpack::pca::PCA C++ class documentation",
"with the smallest eigenvalues.");
// See also...
BINDING_SEE_ALSO("Principal component analysis on Wikipedia",
"https://en.wikipedia.org/wiki/Principal_component_analysis");
BINDING_SEE_ALSO("mlpack::pca::PCA C++ class documentation",
"@doxygen/classmlpack_1_1pca_1_1PCA.html"));
// Parameters for program.
+1 -30
View File
@@ -3,7 +3,7 @@
* @author Matthew Amidon
*
* Definition of the Option class, which is used to define parameters which are
* used by CLI. The ProgramDoc class also resides here.
* used by CLI.
*
* 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
@@ -164,35 +164,6 @@ class CLIOption
}
};
/**
* A static object whose constructor registers program documentation with the
* CLI class. This should not be used outside of CLI itself, and you should use
* the PROGRAM_INFO() macro to declare these objects. Only one ProgramDoc
* object should ever exist.
*
* @see core/util/io.hpp, mlpack::IO
*/
class ProgramDoc
{
public:
/**
* Construct a ProgramDoc object. When constructed, it will register itself
* with IO.
*
* @param programName Short string representing the name of the program.
* @param documentation Long string containing documentation on how to use the
* program and what it is. No newline characters are necessary; this is
* taken care of by IO later.
*/
ProgramDoc(const std::string& programName,
const std::string& documentation);
//! The name of the program.
std::string programName;
//! Documentation for what the program does.
std::string documentation;
};
} // namespace cli
} // namespace bindings
} // namespace mlpack
@@ -102,8 +102,9 @@ inline std::string ProgramCall(const std::string& programName);
/**
* Print what a user would type to invoke the given option name. Note that the
* name *must* exist in the CLI module. (Note that because of the way
* ProgramInfo is structured, this doesn't mean that all of the PARAM_*()
* declarataions need to come before the PROGRAM_INFO() declaration.)
* BINDING_LONG_DESC() and BINDING_EXAMPLE() is structured, this doesn't mean
* that all of the PARAM_*() declarataions need to come before
* BINDING_LONG_DESC() and BINDING_EXAMPLE() declaration.)
*/
inline std::string ParamString(const std::string& paramName);
@@ -138,8 +138,8 @@ std::string ProcessOptions(const std::string& paramName,
else
{
throw std::runtime_error("Unknown parameter '" + paramName + "' " +
"encountered while assembling documentation! Check PROGRAM_INFO() " +
"declaration.");
"encountered while assembling documentation! Check BINDING_LONG_DESC()"
+ " and BINDING_EXAMPLE() declaration.");
}
std::string rest = ProcessOptions(args...);
@@ -229,8 +229,9 @@ inline std::string ProgramCall(const std::string& programName)
/**
* Print what a user would type to invoke the given option name. Note that the
* name *must* exist in the CLI module. (Note that because of the way
* ProgramInfo is structured, this doesn't mean that all of the PARAM_*()
* declarataions need to come before the PROGRAM_INFO() declaration.)
* BINDING_LONG_DESC() and BINDING_EXAMPLE() is structured, this doesn't mean
* that all of the PARAM_*() declarataions need to come before
* BINDING_LONG_DESC() and BINDING_EXAMPLE() declaration.)
*/
inline std::string ParamString(const std::string& paramName)
{
@@ -252,7 +253,7 @@ inline std::string ParamString(const std::string& paramName)
else
{
throw std::runtime_error("Parameter '" + paramName + "' not known! Check "
"PROGRAM_INFO() definition.");
"BINDING_LONG_DESC() and BINDING_EXAMPLE() definition.");
}
}
+10 -6
View File
@@ -25,8 +25,7 @@ void PrintHelp(const std::string& param)
std::string usedParam = param;
std::map<std::string, util::ParamData>& parameters = IO::Parameters();
const std::map<char, std::string>& aliases = IO::Aliases();
util::ProgramDoc& docs = *IO::GetSingleton().doc;
util::BindingDetails& bindingDetails = IO::GetSingleton().doc;
// If we pass a single param, alias it if necessary.
if (usedParam.length() == 1 && aliases.count(usedParam[0]))
usedParam = aliases.at(usedParam[0]);
@@ -64,11 +63,16 @@ void PrintHelp(const std::string& param)
}
// Print out the descriptions.
if (docs.programName != "")
if (bindingDetails.programName != "")
{
std::cout << docs.programName << std::endl << std::endl;
std::cout << " " << util::HyphenateString(docs.documentation(), 2)
<< std::endl << std::endl;
std::cout << bindingDetails.programName << std::endl << std::endl;
std::cout << " " << util::HyphenateString(bindingDetails.longDescription(),
2) << std::endl << std::endl;
for (size_t j = 0; j < bindingDetails.example.size(); ++j)
{
std::cout << " " << util::HyphenateString(bindingDetails.example[j](), 2)
<< std::endl << std::endl;
}
}
else
std::cout << "[undocumented program]" << std::endl << std::endl;
+12 -13
View File
@@ -16,34 +16,33 @@ if (NOT BUILD_GO_BINDINGS)
endif ()
if (BUILD_GO_BINDINGS)
find_package(Go 1.11.0)
if (NOT GO_FOUND)
set(GO_NOT_FOUND_MSG "${GO_NOT_FOUND_MSG}\n - Go")
endif ()
find_package(Gonum)
if (NOT GONUM_FOUND)
set(GO_NOT_FOUND_MSG "${GO_NOT_FOUND_MSG}\n - Gonum")
endif ()
## We need to check here if Golang is even available. Although actually
## technically, I'm not sure if we even need to know! For the tests though we
## do. So it's probably a good idea to check.
if (FORCE_BUILD_GO_BINDINGS)
find_package(Go 1.11.0)
find_package(Gonum)
if (NOT GO_FOUND OR NOT GONUM_FOUND)
unset(BUILD_GO_BINDINGS CACHE)
set(BUILD_GO_SHLIB OFF)
message(FATAL_ERROR "Go or Gonum not found; unable to build Go bindings!")
message(FATAL_ERROR "\nCould not Build Go Bindings; the following modules are not available: ${GO_NOT_FOUND_MSG}")
endif()
else ()
find_package(Go 1.11.0)
find_package(Gonum)
if (NOT GO_FOUND OR NOT GONUM_FOUND)
unset(BUILD_GO_BINDINGS CACHE)
set(BUILD_GO_SHLIB OFF)
not_found_return("Not building Go bindings; the following modules are not available: ${GO_NOT_FOUND_MSG}")
endif()
endif ()
if (NOT GO_FOUND)
not_found_return("Go not found; not building Go bindings.")
endif ()
if (NOT GONUM_FOUND)
not_found_return("Gonum not found; not building Go bindings.")
endif ()
add_custom_target(go)
# All the bindings will build under "src/mlpack.org/v1/mlpack"; So if user build
+1 -1
View File
@@ -45,5 +45,5 @@ int main(int /* argc */, char** /* argv */)
// programName is defined in mlpack_main.hpp.
IO::RestoreSettings(programName);
PrintGo(*IO::GetSingleton().doc, "${PROGRAM_NAME}");
PrintGo(IO::GetSingleton().doc, "${PROGRAM_NAME}");
}
@@ -154,8 +154,8 @@ std::string PrintOptionalInputs(const std::string& paramName,
{
// Unknown parameter!
throw std::runtime_error("Unknown parameter '" + paramName + "' " +
"encountered while assembling documentation! Check PROGRAM_INFO() " +
"declaration.");
"encountered while assembling documentation! Check BINDING_LONG_DESC()"
+ " and BINDING_EXAMPLE() declaration.");
}
// Continue recursion.
@@ -211,8 +211,8 @@ std::string PrintInputOptions(const std::string& paramName,
{
// Unknown parameter!
throw std::runtime_error("Unknown parameter '" + paramName + "' " +
"encountered while assembling documentation! Check PROGRAM_INFO() " +
"declaration.");
"encountered while assembling documentation! Check BINDING_LONG_DESC()"
+ " and BINDING_EXAMPLE() declaration.");
}
// Continue recursion.
@@ -256,8 +256,8 @@ void GetOptions(
{
// Unknown parameter!
throw std::runtime_error("Unknown parameter '" + paramName + "' " +
"encountered while assembling documentation! Check PROGRAM_INFO() " +
"declaration.");
"encountered while assembling documentation! Check BINDING_LONG_DESC()"
+ " and BINDING_EXAMPLE() declaration.");
}
}
+14 -8
View File
@@ -27,14 +27,14 @@ namespace go {
* Given a list of parameter definition and program documentation, print a
* generated .go file to stdout.
*
* @param programInfo Documentation for the program.
* @param doc Documentation for the program.
* @param functionName Name of the function (i.e. "pca").
*/
void PrintGo(const util::ProgramDoc& programInfo,
const std::string& functionName)
void PrintGo(const util::BindingDetails& doc,
const std::string& functionName)
{
// Restore parameters.
IO::RestoreSettings(programInfo.programName);
IO::RestoreSettings(doc.programName);
std::map<std::string, util::ParamData>& parameters = IO::Parameters();
typedef std::map<std::string, util::ParamData>::iterator ParamIter;
@@ -124,8 +124,15 @@ void PrintGo(const util::ProgramDoc& programInfo,
// Print the comment describing the function and its parameters.
cout << "/*" << endl;
cout << " " << HyphenateString(programInfo.documentation(), 2) << endl;
cout << endl << endl;
cout << " " << HyphenateString(doc.longDescription(), 2) << endl << endl;
// Print the examples.
for (size_t j = 0; j < doc.example.size(); ++j)
{
cout << " " << util::HyphenateString(doc.example[j](), 2) << endl << endl;
}
// Next, print information on the input options.
cout << " Input parameters:" << endl;
cout << endl;
for (size_t i = 0; i < inputOptions.size(); ++i)
@@ -216,8 +223,7 @@ void PrintGo(const util::ProgramDoc& programInfo,
cout << " " << "disableVerbose()" << endl;
// Restore the parameters.
cout << " " << "restoreSettings(\"" << programInfo.programName
<< "\")" << endl;
cout << " " << "restoreSettings(\"" << doc.programName << "\")" << endl;
cout << endl;
// Do any input processing.
+2 -3
View File
@@ -22,11 +22,10 @@ namespace go {
/**
* Given a list of parameter definition and program documentation, print a
* generated .go file to stdout.
*
* @param programInfo Documentation for the program.
* @param doc Documentation for the program.
* @param functionName Name of the function (i.e. "pca").
*/
void PrintGo(const util::ProgramDoc& programInfo,
void PrintGo(const util::BindingDetails& doc,
const std::string& functionName);
+1 -1
View File
@@ -3,7 +3,7 @@ add_go_binding(test_go_binding)
if (BUILD_GO_BINDINGS)
add_test(NAME go_binding_test
COMMAND go test -v ${CMAKE_CURRENT_SOURCE_DIR}/go_binding_test.go
COMMAND ${GO_EXECUTABLE} test -v ${CMAKE_CURRENT_SOURCE_DIR}/go_binding_test.go
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/)
set_tests_properties(go_binding_test
PROPERTIES ENVIRONMENT "GOPATH=$ENV{GOPATH}:${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/;
@@ -18,9 +18,16 @@ using namespace std;
using namespace mlpack;
using namespace mlpack::kernel;
PROGRAM_INFO("Golang binding test",
"A simple program to test Golang binding functionality.",
"A simple program to test Golang binding functionality. You can build "
// Program Name.
BINDING_NAME("Golang binding test");
// Short description.
BINDING_SHORT_DESC(
"A simple program to test Go binding functionality.");
// Long description.
BINDING_LONG_DESC(
"A simple program to test Go binding functionality. You can build "
"mlpack with the BUILD_TESTS option set to off, and this binding will "
"no longer be built.");
+1 -1
View File
@@ -35,5 +35,5 @@ int main(int /* argc */, char** /* argv */)
// programName is defined in mlpack_main.hpp.
IO::RestoreSettings(programName);
PrintJL(*IO::GetSingleton().doc, "${NAME}", "${MLPACK_JL_LIB_SUFFIX}");
PrintJL(IO::GetSingleton().doc, "${NAME}", "${MLPACK_JL_LIB_SUFFIX}");
}
@@ -144,8 +144,8 @@ inline std::string CreateInputArguments(const std::string& paramName,
{
// Unknown parameter!
throw std::runtime_error("Unknown parameter '" + paramName + "' " +
"encountered while assembling documentation! Check PROGRAM_INFO() " +
"declaration.");
"encountered while assembling documentation! Check BINDING_LONG_DESC()"
+ " and BINDING_EXAMPLE() declaration.");
}
}
@@ -223,8 +223,8 @@ inline void GetOptions(
{
// Unknown parameter!
throw std::runtime_error("Unknown parameter '" + paramName + "' " +
"encountered while assembling documentation! Check PROGRAM_INFO() " +
"declaration.");
"encountered while assembling documentation! Check BINDING_LONG_DESC()"
+ " and BINDING_EXAMPLE() declaration.");
}
}
+10 -5
View File
@@ -15,7 +15,7 @@
#include <set>
using namespace mlpack;
using namespace mlpack::util;
using namespace std;
namespace mlpack {
@@ -27,12 +27,12 @@ extern std::string programName;
/**
* Print the code for a .jl binding for an mlpack program to stdout.
*/
void PrintJL(const util::ProgramDoc& programInfo,
void PrintJL(const util::BindingDetails& doc,
const string& functionName,
const std::string& mlpackJuliaLibSuffix)
{
// Restore parameters.
IO::RestoreSettings(programInfo.programName);
IO::RestoreSettings(doc.programName);
map<string, util::ParamData>& parameters = IO::Parameters();
typedef map<string, util::ParamData>::iterator ParamIter;
@@ -168,10 +168,15 @@ void PrintJL(const util::ProgramDoc& programInfo,
cout << endl;
// Next print the description.
cout << util::HyphenateString(programInfo.documentation(), 0) << endl;
cout << HyphenateString(doc.longDescription(), 0) << endl << endl;
// Next print the examples.
for (size_t j = 0; j < doc.example.size(); ++j)
{
cout << util::HyphenateString(doc.example[j](), 0) << endl << endl;
}
// Next, print information on the input options.
cout << endl;
cout << "# Arguments" << endl;
cout << endl;
+1 -1
View File
@@ -21,7 +21,7 @@ namespace julia {
/**
* Print the code for a .jl binding for an mlpack program to stdout.
*/
void PrintJL(const util::ProgramDoc& programInfo,
void PrintJL(const util::BindingDetails& doc,
const std::string& functionName,
const std::string& mlpackJuliaLibSuffix);
@@ -18,8 +18,15 @@ using namespace std;
using namespace mlpack;
using namespace mlpack::kernel;
PROGRAM_INFO("Julia binding test",
"A simple program to test Julia binding functionality.",
// Program Name.
BINDING_NAME("Julia binding test");
// Short description.
BINDING_SHORT_DESC(
"A simple program to test Julia binding functionality.");
// Long description.
BINDING_LONG_DESC(
"A simple program to test Julia binding functionality. You can build "
"mlpack with the BUILD_TESTS option set to off, and this binding will "
"no longer be built.");
@@ -17,7 +17,8 @@ namespace mlpack {
namespace bindings {
namespace markdown {
util::ProgramDoc& BindingInfo::GetProgramDoc(const std::string& bindingName)
util::BindingDetails& BindingInfo::GetBindingDetails(
const std::string& bindingName)
{
if (GetSingleton().map.count(bindingName) == 0)
{
@@ -28,14 +29,6 @@ util::ProgramDoc& BindingInfo::GetProgramDoc(const std::string& bindingName)
return GetSingleton().map.at(bindingName);
}
//! Register a ProgramDoc object with the given bindingName.
void BindingInfo::RegisterProgramDoc(const std::string& bindingName,
const util::ProgramDoc& programDoc)
{
GetSingleton().map[bindingName] = programDoc;
}
//! Get or modify the current language (don't set it to something invalid!).
std::string& BindingInfo::Language()
{
+12 -15
View File
@@ -4,7 +4,7 @@
*
* This file defines the BindingInfo singleton class that is used specifically
* for the Markdown bindings to map from a binding name (i.e. "knn") to
* multiple ProgramDoc objects, which are then used to generate the
* multiple documentation objects, which are then used to generate the
* documentation.
*
* mlpack is free software; you may redistribute it and/or modify it under the
@@ -16,7 +16,7 @@
#define MLPACK_BINDINGS_MARKDOWN_BINDING_NAME_HPP
#include <mlpack/prereqs.hpp>
#include <mlpack/core/util/program_doc.hpp>
#include <mlpack/core/util/binding_details.hpp>
namespace mlpack {
namespace bindings {
@@ -24,31 +24,28 @@ namespace markdown {
/**
* The BindingInfo class is used by the Markdown documentation generator to
* store multiple ProgramDoc objects, indexed by both the binding name (i.e.
* store multiple documentation objects, indexed by both the binding name (i.e.
* "knn") and the language (i.e. "cli").
*/
class BindingInfo
{
public:
//! Return a ProgramDoc object for a given bindingName.
static util::ProgramDoc& GetProgramDoc(const std::string& bindingName);
//! Register a ProgramDoc object with the given bindingName.
static void RegisterProgramDoc(const std::string& bindingName,
const util::ProgramDoc& programDoc);
//! Return a BindingDetails object for a given bindingName.
static util::BindingDetails& GetBindingDetails(
const std::string& bindingName);
//! Get or modify the current language (don't set it to something invalid!).
static std::string& Language();
private:
//! Private constructor, so that only one instance can be created.
BindingInfo() { }
//! Get the singleton.
static BindingInfo& GetSingleton();
//! Internally-held map for mapping a binding name to a ProgramDoc name.
std::unordered_map<std::string, util::ProgramDoc> map;
//! Internally-held map for mapping a binding name to a BindingDetails.
std::unordered_map<std::string, util::BindingDetails> map;
private:
//! Private constructor, so that only one instance can be created.
BindingInfo() { }
//! Holds the name of the language that we are currently printing. This is
//! modified before printing the documentation, and then used by
@@ -12,7 +12,7 @@
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#define BINDING_NAME "${BINDING}"
#define MARKDOWN_BINDING_NAME "${BINDING}"
#include <mlpack/core.hpp>
#include "generate_markdown.${BINDING}.hpp"
@@ -88,8 +88,9 @@ inline std::string ProgramCall(const std::string& programName);
/**
* Print what a user would type to invoke the given option name. Note that the
* name *must* exist in the IO module. (Note that because of the way
* ProgramInfo is structured, this doesn't mean that all of the PARAM_*()
* declarataions need to come before the PROGRAM_INFO() declaration.)
* BINDING_LONG_DESC() and BINDING_EXAMPLE() is structured, this doesn't mean
* that all of the PARAM_*() declarataions need to come before
* BINDING_LONG_DESC() and BINDING_EXAMPLE() declaration.)
*/
inline std::string ParamString(const std::string& paramName);
@@ -596,8 +596,9 @@ inline std::string ProgramCall(const std::string& programName)
/**
* Print what a user would type to invoke the given option name. Note that the
* name *must* exist in the CLI module. (Note that because of the way
* ProgramInfo is structured, this doesn't mean that all of the PARAM_*()
* declarataions need to come before the PROGRAM_INFO() declaration.)
* BINDING_LONG_DESC() and BINDING_EXAMPLE() is structured, this doesn't mean
* that all of the PARAM_*() declarataions need to come before
* BINDING_LONG_DESC() and BINDING_EXAMPLE() declaration.)
*/
inline std::string ParamString(const std::string& paramName)
{
+24 -17
View File
@@ -12,7 +12,7 @@
#include "print_docs.hpp"
#include <mlpack/core/util/io.hpp>
#include <mlpack/core/util/program_doc.hpp>
#include <mlpack/core/util/binding_details.hpp>
#include "binding_info.hpp"
#include "print_doc_functions.hpp"
@@ -45,7 +45,7 @@ void PrintHeaders(const std::string& bindingName,
void PrintDocs(const std::string& bindingName,
const vector<string>& languages)
{
ProgramDoc& programDoc = BindingInfo::GetProgramDoc(bindingName);
BindingDetails& doc = BindingInfo::GetBindingDetails(bindingName);
IO::RestoreSettings(bindingName);
@@ -64,7 +64,7 @@ void PrintDocs(const std::string& bindingName,
// Next, print the logical name of the binding (that's known by
// ProgramInfo).
cout << "#### " << programDoc.programName << endl;
cout << "#### " << doc.programName << endl;
cout << endl;
for (size_t i = 0; i < languages.size(); ++i)
@@ -78,7 +78,7 @@ void PrintDocs(const std::string& bindingName,
}
cout << endl;
cout << programDoc.shortDocumentation << " ";
cout << doc.shortDescription << " ";
for (size_t i = 0; i < languages.size(); ++i)
{
cout << "[Detailed documentation](#" << languages[i] << "_"
@@ -213,37 +213,44 @@ void PrintDocs(const std::string& bindingName,
cout << "{: #" << languages[i] << "_" << bindingName
<< "_detailed-documentation }" << endl;
cout << endl;
string doc = boost::replace_all_copy(programDoc.documentation(),
"|", "\\|");
cout << doc << endl;
cout << endl;
string desc = boost::replace_all_copy(doc.longDescription(),
"|", "\\|");
cout << desc << endl << endl;
if (doc.example.size() > 0)
cout << "### Example" << endl;
for (size_t j = 0; j < doc.example.size(); ++j)
{
string eg = boost::replace_all_copy(doc.example[j](),
"|", "\\|");
cout << eg << endl << endl;
}
cout << "### See also" << endl;
cout << endl;
for (size_t j = 0; j < programDoc.seeAlso.size(); ++j)
for (size_t j = 0; j < doc.seeAlso.size(); ++j)
{
cout << " - " << "[";
// We need special processing if the user has specified a binding name
// starting with @ (i.e., '@kfn' or similar).
if (programDoc.seeAlso[j].first[0] == '@')
cout << GetBindingName(programDoc.seeAlso[j].first.substr(1));
if (doc.seeAlso[j].first[0] == '@')
cout << GetBindingName(doc.seeAlso[j].first.substr(1));
else
cout << programDoc.seeAlso[j].first;
cout << doc.seeAlso[j].first;
cout << "](";
// We need special handling of Doxygen information.
if (programDoc.seeAlso[j].second.substr(0, 8) == "@doxygen")
if (doc.seeAlso[j].second.substr(0, 8) == "@doxygen")
{
cout << DOXYGEN_PREFIX << programDoc.seeAlso[j].second.substr(9);
cout << DOXYGEN_PREFIX << doc.seeAlso[j].second.substr(9);
}
else if (programDoc.seeAlso[j].second[0] == '#')
else if (doc.seeAlso[j].second[0] == '#')
{
cout << "#" << languages[i] << "_"
<< programDoc.seeAlso[j].second.substr(1);
<< doc.seeAlso[j].second.substr(1);
}
else
{
cout << programDoc.seeAlso[j].second;
cout << doc.seeAlso[j].second;
}
cout << ")" << endl;
@@ -2,8 +2,9 @@
* @file bindings/markdown/program_doc_wrapper.hpp
* @author Ryan Curtin
*
* A simple wrapper around ProgramDoc that also calls
* BindingInfo::RegisterProgramDoc() upon construction.
* A simple wrapper around programName, shortDescription, longDescription,
* example and seeAlso that also respectively register all the macros upon
* construction.
*
* 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
@@ -19,23 +20,73 @@ namespace mlpack {
namespace bindings {
namespace markdown {
class ProgramDocWrapper
class ProgramNameWrapper
{
public:
/**
* Construct a ProgramDoc object and register it with
* BindingInfo::RegisterProgramDoc().
* Register programName.
*/
ProgramDocWrapper(const std::string& bindingName,
const std::string& programName,
const std::string& shortDocumentation,
const std::function<std::string()>& documentation,
const std::vector<std::pair<std::string, std::string>>&
seeAlso)
ProgramNameWrapper(const std::string& bindingName,
const std::string& programName)
{
util::ProgramDoc pd(programName, shortDocumentation, documentation,
seeAlso);
BindingInfo::RegisterProgramDoc(bindingName, pd);
BindingInfo::GetSingleton().map[bindingName].programName =
std::move(programName);
}
};
class ShortDescriptionWrapper
{
public:
/**
* Register shortDescription.
*/
ShortDescriptionWrapper(const std::string& bindingName,
const std::string& shortDescription)
{
BindingInfo::GetSingleton().map[bindingName].shortDescription =
std::move(shortDescription);
}
};
class LongDescriptionWrapper
{
public:
/**
* Register longDescription.
*/
LongDescriptionWrapper(const std::string& bindingName,
const std::function<std::string()>& longDescription)
{
BindingInfo::GetSingleton().map[bindingName].longDescription =
std::move(longDescription);
}
};
class ExampleWrapper
{
public:
/**
* Register example.
*/
ExampleWrapper(const std::string& bindingName,
const std::function<std::string()>& example)
{
BindingInfo::GetSingleton().map[bindingName].example.push_back(
std::move(example));
}
};
class SeeAlsoWrapper
{
public:
/**
* Register seeAlso.
*/
SeeAlsoWrapper(const std::string& bindingName,
const std::string& description, const std::string& link)
{
BindingInfo::GetSingleton().map[bindingName].seeAlso.push_back(
std::move(std::make_pair(description, link)));
}
};
+24 -11
View File
@@ -14,32 +14,45 @@ if (NOT BUILD_PYTHON_BINDINGS)
endif ()
# Generate Python setuptools file.
find_package(PythonInterp)
if (NOT PYTHON_EXECUTABLE)
not_found_return("Python not found; not building Python bindings.")
else ()
message(STATUS "Found Python: ${PYTHON_EXECUTABLE}")
endif ()
# Import find_python_module.
include(${CMAKE_SOURCE_DIR}/CMake/FindPythonModule.cmake)
find_package(PythonInterp)
if (NOT PYTHON_EXECUTABLE)
set(PY_NOT_FOUND_MSG "${PY_NOT_FOUND_MSG}\n - Python")
endif()
find_python_module(distutils)
if (NOT PY_DISTUTILS)
not_found_return("distutils not found; not building Python bindings.")
set(PY_NOT_FOUND_MSG "${PY_NOT_FOUND_MSG}\n - distutils")
endif ()
find_python_module(Cython 0.24)
if (NOT PY_CYTHON)
not_found_return("Cython not found; not building Python bindings.")
set(PY_NOT_FOUND_MSG "${PY_NOT_FOUND_MSG}\n - Cython")
endif ()
find_python_module(numpy)
if (NOT PY_NUMPY)
not_found_return("numpy not found; not building Python bindings.")
set(PY_NOT_FOUND_MSG "${PY_NOT_FOUND_MSG}\n - numpy")
endif ()
find_python_module(pandas 0.15.0)
if (NOT PY_PANDAS)
not_found_return("pandas not found; not building Python bindings.")
set(PY_NOT_FOUND_MSG "${PY_NOT_FOUND_MSG}\n - pandas")
endif ()
## We need to check here if Python and other dependencies is even available, as
## it is require to build python-bindings.
if (FORCE_BUILD_PYTHON_BINDINGS)
if (NOT PYTHON_EXECUTABLE OR NOT PY_DISTUTILS OR NOT PY_CYTHON OR NOT PY_NUMPY
OR NOT PY_PANDAS)
unset(BUILD_PYTHON_BINDINGS CACHE)
message(FATAL_ERROR "\nCould not Build Python Bindings; the following modules are not available: ${PY_NOT_FOUND_MSG}")
endif()
else()
if (NOT PYTHON_EXECUTABLE OR NOT PY_DISTUTILS OR NOT PY_CYTHON OR NOT PY_NUMPY
OR NOT PY_PANDAS)
unset(BUILD_PYTHON_BINDINGS CACHE)
not_found_return("Not building Python bindings; the following modules are not available: ${PY_NOT_FOUND_MSG}")
endif()
endif()
set(BUILDING_PYTHON_BINDINGS ON PARENT_SCOPE)
# Nothing in this directory will be compiled into mlpack.
@@ -45,6 +45,5 @@ int main(int /* argc */, char** /* argv */)
// programName is defined in mlpack_main.hpp.
IO::RestoreSettings(programName);
PrintPYX(*IO::GetSingleton().doc, "${PROGRAM_MAIN_FILE}",
"${PROGRAM_NAME}");
PrintPYX(IO::GetSingleton().doc, "${PROGRAM_MAIN_FILE}", "${PROGRAM_NAME}");
}
@@ -133,8 +133,8 @@ std::string PrintInputOptions(const std::string& paramName,
{
// Unknown parameter!
throw std::runtime_error("Unknown parameter '" + paramName + "' " +
"encountered while assembling documentation! Check PROGRAM_INFO() " +
"declaration.");
"encountered while assembling documentation! Check BINDING_LONG_DESC()"
+ " and BINDING_EXAMPLE() declaration.");
}
// Continue recursion.
@@ -172,8 +172,8 @@ std::string PrintOutputOptions(const std::string& paramName,
{
// Unknown parameter!
throw std::runtime_error("Unknown parameter '" + paramName + "' " +
"encountered while assembling documentation! Check PROGRAM_INFO() " +
"declaration.");
"encountered while assembling documentation! Check BINDING_LONG_DESC()"
+ " and BINDING_EXAMPLE() declaration.");
}
// Continue recursion.
+16 -8
View File
@@ -26,18 +26,17 @@ namespace python {
* Given a list of parameter definition and program documentation, print a
* generated .pyx file to stdout.
*
* @param parameters List of parameters the program will use (from IO).
* @param programInfo Documentation for the program.
* @param doc Documentation for the program.
* @param mainFilename Filename of the main program (i.e.
* "/path/to/pca_main.cpp").
* @param functionName Name of the function (i.e. "pca").
*/
void PrintPYX(const ProgramDoc& programInfo,
void PrintPYX(const util::BindingDetails& doc,
const string& mainFilename,
const string& functionName)
{
// Restore parameters.
IO::RestoreSettings(programInfo.programName);
IO::RestoreSettings(doc.programName);
std::map<std::string, util::ParamData>& parameters = IO::Parameters();
typedef std::map<std::string, util::ParamData>::iterator ParamIter;
@@ -143,10 +142,19 @@ void PrintPYX(const ProgramDoc& programInfo,
// Print the comment describing the function and its parameters.
cout << " \"\"\"" << endl;
cout << " " << programInfo.programName << endl;
cout << " " << doc.programName << endl;
cout << endl;
cout << " " << HyphenateString(programInfo.documentation(), 2) << endl;
cout << endl << endl;
// Print the description.
cout << " " << HyphenateString(doc.longDescription(), 2) << endl << endl;
// Next print the examples.
for (size_t j = 0; j < doc.example.size(); ++j)
{
cout << " " << util::HyphenateString(doc.example[j](), 2) << endl << endl;
}
// Next, print information on the input options.
cout << " Input parameters:" << endl;
cout << endl;
for (size_t i = 0; i < inputOptions.size(); ++i)
@@ -184,7 +192,7 @@ void PrintPYX(const ProgramDoc& programInfo,
cout << " DisableVerbose()" << endl;
// Restore the parameters.
cout << " IO.RestoreSettings(\"" << programInfo.programName << "\")"
cout << " IO.RestoreSettings(\"" << doc.programName << "\")"
<< endl;
// Determine whether or not we need to copy parameters.
+2 -2
View File
@@ -23,12 +23,12 @@ namespace python {
* Given a list of parameter definition and program documentation, print a
* generated .pyx file to stdout.
*
* @param programInfo Documentation for the program.
* @param doc Documentation for the program.
* @param mainFilename Filename of the main program (i.e.
* "/path/to/pca_main.cpp").
* @param functionName Name of the function (i.e. "pca").
*/
void PrintPYX(const util::ProgramDoc& programInfo,
void PrintPYX(const util::BindingDetails& doc,
const std::string& mainFilename,
const std::string& functionName);
@@ -18,8 +18,15 @@ using namespace std;
using namespace mlpack;
using namespace mlpack::kernel;
PROGRAM_INFO("Python binding test",
"A simple program to test Python binding functionality.",
// Program Name.
BINDING_NAME("Python binding test");
// Short description.
BINDING_SHORT_DESC(
"A simple program to test Python binding functionality.");
// Long description.
BINDING_LONG_DESC(
"A simple program to test Python binding functionality. You can build "
"mlpack with the BUILD_TESTS option set to off, and this binding will "
"no longer be built.");
-29
View File
@@ -108,35 +108,6 @@ class TestOption
}
};
/**
* A static object whose constructor registers program documentation with the
* IO class. This should not be used outside of IO itself, and you should use
* the PROGRAM_INFO() macro to declare these objects. Only one ProgramDoc
* object should ever exist.
*
* @see core/util/io.hpp, mlpack::IO
*/
class ProgramDoc
{
public:
/**
* Construct a ProgramDoc object. When constructed, it will register itself
* with IO.
*
* @param programName Short string representing the name of the program.
* @param documentation Long string containing documentation on how to use the
* program and what it is. No newline characters are necessary; this is
* taken care of by IO later.
*/
ProgramDoc(const std::string& programName,
const std::string& documentation);
//! The name of the program.
std::string programName;
//! Documentation for what the program does.
std::string documentation;
};
} // namespace tests
} // namespace bindings
} // namespace mlpack
+2
View File
@@ -10,6 +10,8 @@ set(SOURCES
log_add.hpp
log_add_impl.hpp
make_alias.hpp
multiply_slices_impl.hpp
multiply_slices.hpp
random.hpp
random.cpp
random_basis.hpp
+78
View File
@@ -0,0 +1,78 @@
/**
* @file core/math/multiply_slices.hpp
* @author Mrityunjay Tripathi
*
* Function to perform matrix multiplication on cubes.
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_CORE_MATH_MULTIPLY_SLICES_HPP
#define MLPACK_CORE_MATH_MULTIPLY_SLICES_HPP
#include <mlpack/prereqs.hpp>
namespace mlpack {
namespace math /** Miscellaneous math routines. */ {
/**
* Matrix multiplication of slices of two cubes. This function expects
* both cubes to have the same number of slices. For example, a valid operation
* would be: cube A of shape (m, p, s) multiplied by cube B of shape (p, n, s)
* resulting in a cube of shape (m, n, s).
*
* @param cubeA First cube.
* @param cubeB Second cube.
* @param aTranspose Whether slices of first cube have to be transposed.
* @param bTranspose Whether slices of second cube have to be transposed.
*/
template <typename CubeType>
CubeType MultiplyCube2Cube(const CubeType& cubeA,
const CubeType& cubeB,
const bool aTranspose = false,
const bool bTranspose = false);
/**
* Matrix multiplication of a matrix and all the slices of a cube. This function
* is used when the first object is a matrix and the second object is a cube.
* For example, a valid operation would be: matrix A of shape (m, p)
* multiplied by cube B of shape (p, n, s) resulting in a cube
* of shape (m, n, s).
*
* @param matA The matrix as the first operand.
* @param cubeB The cube as the second operand.
* @param aTranspose Whether matrix has to be transposed.
* @param bTranspose Whether slices of cube have to be transposed.
*/
template <typename MatType, typename CubeType>
CubeType MultiplyMat2Cube(const MatType& matA,
const CubeType& cubeB,
const bool aTranspose = false,
const bool bTranspose = false);
/**
* Matrix multiplication of all slices of a cube with a matrix. This function
* is used when the first object is a cube and the second object is a matrix.
* For example, a valid operation would be: cube A of shape (m, p, s)
* multiplied by a matrix of shape (p, n) resulting in a cube
* of shape (m, n, s).
*
* @param cubeA The cube as the first operand.
* @param matB The matrix as the second operand.
* @param aTranspose Whether slices of cube have to be transposed.
* @param bTranspose Whether matrix has to be transposed.
*/
template <typename CubeType, typename MatType>
CubeType MultiplyCube2Mat(const CubeType& cubeA,
const MatType& matB,
const bool aTranspose = false,
const bool bTranspose = false);
} // namespace math
} // namespace mlpack
// Include implementation.
#include "multiply_slices_impl.hpp"
#endif
@@ -0,0 +1,199 @@
/**
* @file core/math/multiply_slices_impl.hpp
* @author Mrityunjay Tripathi
*
* Implementation of matrix multiplication over slices.
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_CORE_MATH_MULTIPLY_SLICES_IMPL_HPP
#define MLPACK_CORE_MATH_MULTIPLY_SLICES_IMPL_HPP
#include "multiply_slices.hpp"
namespace mlpack {
namespace math /** Miscellaneous math routines. */ {
template <typename CubeType>
CubeType MultiplyCube2Cube(const CubeType& cubeA,
const CubeType& cubeB,
const bool aTranspose,
const bool bTranspose)
{
size_t rows = cubeA.n_rows, cols = cubeB.n_cols, slices = cubeA.n_slices;
if (cubeA.n_slices != cubeB.n_slices)
Log::Fatal << "Number of slices is not same in both cubes." << std::endl;
if (aTranspose && bTranspose)
{
if (cubeA.n_rows != cubeB.n_cols)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
rows = cubeA.n_cols;
cols = cubeB.n_rows;
}
else if (bTranspose && !aTranspose)
{
if (cubeA.n_cols != cubeB.n_cols)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
cols = cubeB.n_rows;
}
else if (aTranspose && !bTranspose)
{
if (cubeA.n_rows != cubeB.n_rows)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
rows = cubeA.n_cols;
}
else
{
if (cubeA.n_cols != cubeB.n_rows)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
}
CubeType z(rows, cols, slices);
if (aTranspose && bTranspose)
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = arma::trans(cubeB.slice(i) * cubeA.slice(i));
}
else if (bTranspose && !aTranspose)
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = cubeA.slice(i) * cubeB.slice(i).t();
}
else if (aTranspose && !bTranspose)
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = cubeA.slice(i).t() * cubeB.slice(i);
}
else
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = cubeA.slice(i) * cubeB.slice(i);
}
return z;
}
template <typename MatType, typename CubeType>
CubeType MultiplyMat2Cube(const MatType& matA,
const CubeType& cubeB,
const bool aTranspose,
const bool bTranspose)
{
size_t rows = matA.n_rows, cols = cubeB.n_cols, slices = cubeB.n_slices;
if (aTranspose && bTranspose)
{
if (matA.n_rows != cubeB.n_cols)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
rows = matA.n_cols;
cols = cubeB.n_rows;
}
else if (bTranspose && !aTranspose)
{
if (matA.n_cols != cubeB.n_cols)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
cols = cubeB.n_rows;
}
else if (aTranspose && !bTranspose)
{
if (matA.n_rows != cubeB.n_rows)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
rows = matA.n_cols;
}
else
{
if (matA.n_cols != cubeB.n_rows)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
}
CubeType z(rows, cols, slices);
if (aTranspose && bTranspose)
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = arma::trans(cubeB.slice(i) * matA);
}
else if (bTranspose)
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = matA * cubeB.slice(i).t();
}
else if (aTranspose)
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = matA.t() * cubeB.slice(i);
}
else
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = matA * cubeB.slice(i);
}
return z;
}
template <typename CubeType, typename MatType>
CubeType MultiplyCube2Mat(const CubeType& cubeA,
const MatType& matB,
const bool aTranspose,
const bool bTranspose)
{
size_t rows = cubeA.n_rows, cols = matB.n_cols, slices = cubeA.n_slices;
if (aTranspose && bTranspose)
{
if (cubeA.n_rows != matB.n_cols)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
rows = cubeA.n_cols;
cols = matB.n_rows;
}
else if (bTranspose && !aTranspose)
{
if (cubeA.n_cols != matB.n_cols)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
cols = matB.n_rows;
}
else if (aTranspose && !bTranspose)
{
if (cubeA.n_rows != matB.n_rows)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
rows = cubeA.n_cols;
}
else
if (cubeA.n_cols != matB.n_rows)
Log::Fatal << "Matrix multiplication invalid!" << std::endl;
CubeType z(rows, cols, slices);
if (aTranspose && bTranspose)
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = arma::trans(matB * cubeA.slice(i));
}
else if (bTranspose && !aTranspose)
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = cubeA.slice(i) * matB.t();
}
else if (aTranspose && !bTranspose)
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = cubeA.slice(i).t() * matB;
}
else
{
for (size_t i = 0; i < slices; ++i)
z.slice(i) = cubeA.slice(i) * matB;
}
return z;
}
} // namespace math
} // namespace mlpack
#endif
+1
View File
@@ -6,6 +6,7 @@ set(SOURCES
arma_config_check.hpp
backtrace.hpp
backtrace.cpp
binding_details.hpp
io.hpp
io.cpp
io_impl.hpp
+44
View File
@@ -0,0 +1,44 @@
/**
* @file core/util/binding_details.hpp
* @author Yashwant Singh Parihar
*
* This defines the structure that holds documentation details for bindings.
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_CORE_UTIL_BINDING_DETAILS_HPP
#define MLPACK_CORE_UTIL_BINDING_DETAILS_HPP
#include <mlpack/prereqs.hpp>
#include "program_doc.hpp"
namespace mlpack {
namespace util {
/**
* This structure holds all of the information about bindings documentation.
*/
struct BindingDetails
{
//! Name of the binding.
std::string programName;
//! A short two-sentence description of the binding, what it does, and what
//! it is useful for.
std::string shortDescription;
//! Long string containing documentation on what it is. No newline characters
//! are necessary; this is taken care of by IO later.
std::function<std::string()> longDescription;
//! Documentation on how to use the binding.
std::vector<std::function<std::string()>> example;
//! A set of pairs of strings with useful "see also" information; each pair
//! is <description, url>.
std::vector<std::pair<std::string, std::string>> seeAlso;
};
} // namespace util
} // namespace mlpack
#endif
+4 -22
View File
@@ -17,19 +17,15 @@
using namespace mlpack;
using namespace mlpack::util;
// Fake ProgramDoc in case none is supplied.
static ProgramDoc emptyProgramDoc = ProgramDoc("", "", []() { return ""; },
{});
/* Constructors, Destructors, Copy */
/* Make the constructor private, to preclude unauthorized instances */
IO::IO() : didParse(false), doc(&emptyProgramDoc)
IO::IO() : didParse(false)
{
return;
}
// Private copy constructor; don't want copies floating around.
IO::IO(const IO& /* other */) : didParse(false), doc(&emptyProgramDoc)
IO::IO(const IO& /* other */) : didParse(false)
{
return;
}
@@ -154,20 +150,6 @@ IO& IO::GetSingleton()
return singleton;
}
/**
* Registers a ProgramDoc object, which contains documentation about the
* program.
*
* @param doc Pointer to the ProgramDoc object.
*/
void IO::RegisterProgramDoc(ProgramDoc* doc)
{
// Only register the doc if it is not the dummy object we created at the
// beginning of the file (as a default value in case this is never called).
if (doc != &emptyProgramDoc)
GetSingleton().doc = doc;
}
// Get the parameters that the IO object knows about.
std::map<std::string, ParamData>& IO::Parameters()
{
@@ -180,10 +162,10 @@ std::map<char, std::string>& IO::Aliases()
return GetSingleton().aliases;
}
// Get the program name as set by PROGRAM_INFO().
// Get the program name as set by BINDING_NAME().
std::string IO::ProgramName()
{
return GetSingleton().doc->programName;
return GetSingleton().doc.programName;
}
// Set a particular parameter as passed.
+23 -29
View File
@@ -23,6 +23,7 @@
#include <mlpack/prereqs.hpp>
#include "timers.hpp"
#include "binding_details.hpp"
#include "program_doc.hpp"
#include "version.hpp"
@@ -32,13 +33,6 @@
#include <mlpack/core/data/save.hpp>
namespace mlpack {
namespace util {
// Externally defined in option.hpp, this class holds information about the
// program being run.
class ProgramDoc;
} // namespace util
/**
* @brief Parses the command line for parameters and holds user-specified
@@ -76,7 +70,7 @@ class ProgramDoc;
* merely as a flag on the command line (no '=true' is required).
*
* Here is an example of a few parameters being defined; this is for the KNN
* executable (methods/neighbor_search/knn_main.cpp):
* binding (methods/neighbor_search/knn_main.cpp):
*
* @code
* PARAM_STRING_REQ("reference_file", "File containing the reference dataset.",
@@ -99,14 +93,24 @@ class ProgramDoc;
* @section programinfo Documenting the program itself
*
* In addition to allowing documentation for each individual parameter and
* module, the PROGRAM_INFO() macro provides support for documenting the program
* itself. There should only be one instance of the PROGRAM_INFO() macro.
* module, the BINDING_NAME() macro provides support for documenting the
* programName, BINDING_SHORT_DESC() macro provides support for documenting the
* shortDescription, BINDING_LONG_DESC() macro provides support for documenting
* the longDescription, the BINDING_EXAMPLE() macro provides support for
* documenting the example and the BINDING_SEE_ALSO() macro provides support for
* documenting the seeAlso. There should only be one instance of the
* BINDING_NAME(), BINDING_SHORT_DESC() and BINDING_LONG_DESC() macros and there
* can be multiple instance of BINDING_EXAMPLE() and BINDING_SEE_ALSO() macro.
* Below is an example:
*
* @code
* PROGRAM_INFO("Maximum Variance Unfolding", "This program performs maximum "
* BINDING_NAME("Maximum Variance Unfolding");
* BINDING_SHORT_DESC("An implementation of Maximum Variance Unfolding");
* BINDING_LONG_DESC( "This program performs maximum "
* "variance unfolding on the given dataset, writing a lower-dimensional "
* "unfolded dataset to the given output file.");
* BINDING_EXAMPLE("mvu", "input", "dataset", "new_dim", 5, "output", "output");
* BINDING_SEE_ALSO("Perceptron", "#perceptron");
* @endcode
*
* This description should be verbose, and explain to a non-expert user what the
@@ -152,10 +156,10 @@ class ProgramDoc;
*
* @note
* Options should only be defined in files which define `main()` (that is, main
* executables). If options are defined elsewhere, they may be spuriously
* included into other executables and confuse users. Similarly, if your
* executable has options which you did not define, it is probably because the
* option is defined somewhere else and included in your executable.
* bindings). If options are defined elsewhere, they may be spuriously
* included into other bindings and confuse users. Similarly, if your
* binding has options which you did not define, it is probably because the
* option is defined somewhere else and included in your binding.
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -240,21 +244,12 @@ class IO
*/
static IO& GetSingleton();
/**
* Registers a ProgramDoc object, which contains documentation about the
* program. If this method has been called before (that is, if two
* ProgramDocs are instantiated in the program), a fatal error will occur.
*
* @param doc Pointer to the ProgramDoc object.
*/
static void RegisterProgramDoc(util::ProgramDoc* doc);
//! Return a modifiable list of parameters that IO knows about.
static std::map<std::string, util::ParamData>& Parameters();
//! Return a modifiable list of aliases that IO knows about.
static std::map<char, std::string>& Aliases();
//! Get the program name as set by the PROGRAM_INFO() macro.
//! Get the program name as set by the BINDING_NAME() macro.
static std::string ProgramName();
/**
@@ -313,7 +308,7 @@ class IO
bool didParse;
//! Holds the name of the program for --version. This is the true program
//! name (argv[0]) not what is given in ProgramDoc.
//! name (argv[0]) not what is given in BindingDetails.
std::string programName;
//! Holds the timer objects.
@@ -322,9 +317,8 @@ class IO
//! So that Timer::Start() and Timer::Stop() can access the timer variable.
friend class Timer;
//! Pointer to the ProgramDoc object.
util::ProgramDoc* doc;
//! Holds the bindingDetails objects.
util::BindingDetails doc;
private:
/**
* Make the constructor private, to preclude unauthorized instances.
+66 -30
View File
@@ -152,12 +152,6 @@ using Option = mlpack::bindings::tests::TestOption<T>;
// testName symbol should be defined in each binding test file
#include <mlpack/core/util/param.hpp>
#undef PROGRAM_INFO
#define PROGRAM_INFO(NAME, SHORT_DESC, DESC, ...) \
static mlpack::util::ProgramDoc \
io_programdoc_dummy_object = mlpack::util::ProgramDoc(NAME, SHORT_DESC, \
[]() { return DESC; }, { __VA_ARGS__ })
#elif(BINDING_TYPE == BINDING_TYPE_PYX) // This is a Python binding.
// Matrices are transposed on load/save.
@@ -217,11 +211,10 @@ using Option = mlpack::bindings::python::PyOption<T>;
static const std::string testName = "";
#include <mlpack/core/util/param.hpp>
#undef PROGRAM_INFO
#define PROGRAM_INFO(NAME, SHORT_DESC, DESC, ...) \
static mlpack::util::ProgramDoc \
io_programdoc_dummy_object = mlpack::util::ProgramDoc(NAME, SHORT_DESC, \
[]() { return DESC; }, { __VA_ARGS__ }); \
#undef BINDING_NAME
#define BINDING_NAME(NAME) static \
mlpack::util::ProgramName \
io_programname_dummy_object = mlpack::util::ProgramName(NAME); \
namespace mlpack { \
namespace bindings { \
namespace python { \
@@ -266,11 +259,10 @@ using Option = mlpack::bindings::julia::JuliaOption<T>;
static const std::string testName = "";
#include <mlpack/core/util/param.hpp>
#undef PROGRAM_INFO
#define PROGRAM_INFO(NAME, SHORT_DESC, DESC, ...) static \
mlpack::util::ProgramDoc \
io_programdoc_dummy_object = mlpack::util::ProgramDoc(NAME, SHORT_DESC, \
[]() { return DESC; }, { __VA_ARGS__ }); \
#undef BINDING_NAME
#define BINDING_NAME(NAME) static \
mlpack::util::ProgramName \
io_programname_dummy_object = mlpack::util::ProgramName(NAME); \
namespace mlpack { \
namespace bindings { \
namespace julia { \
@@ -311,11 +303,10 @@ using Option = mlpack::bindings::go::GoOption<T>;
static const std::string testName = "";
#include <mlpack/core/util/param.hpp>
#undef PROGRAM_INFO
#define PROGRAM_INFO(NAME, SHORT_DESC, DESC, ...) \
static mlpack::util::ProgramDoc \
io_programdoc_dummy_object = mlpack::util::ProgramDoc(NAME, SHORT_DESC, \
[]() { return DESC; }, { __VA_ARGS__ }); \
#undef BINDING_NAME
#define BINDING_NAME(NAME) static \
mlpack::util::ProgramName \
io_programname_dummy_object = mlpack::util::ProgramName(NAME); \
namespace mlpack { \
namespace bindings { \
namespace go { \
@@ -331,9 +322,11 @@ PARAM_FLAG("verbose", "Display informational messages and the full list of "
#elif BINDING_TYPE == BINDING_TYPE_MARKDOWN
// We use BINDING_NAME in PROGRAM_INFO() so it needs to be defined.
#ifndef BINDING_NAME
#error "BINDING_NAME must be defined when BINDING_TYPE is Markdown!"
// We use MARKDOWN_BINDING_NAME in BINDING_NAME(), BINDING_SHORT_DESC(),
// BINDING_LONG_DESC(), BINDING_EXAMPLE() and BINDING_SEE_ALSO()
// so it needs to be defined.
#ifndef MARKDOWN_BINDING_NAME
#error "MARKDOWN_BINDING_NAME must be defined when BINDING_TYPE is Markdown!"
#endif
// This value doesn't actually matter, but it needs to be defined as something.
@@ -396,12 +389,55 @@ using Option = mlpack::bindings::markdown::MDOption<T>;
#include <mlpack/core/util/param.hpp>
#include <mlpack/bindings/markdown/program_doc_wrapper.hpp>
#undef PROGRAM_INFO
#define PROGRAM_INFO(NAME, SHORT_DESC, DESC, ...) static \
mlpack::bindings::markdown::ProgramDocWrapper \
io_programdoc_dummy_object = \
mlpack::bindings::markdown::ProgramDocWrapper(BINDING_NAME, NAME, \
SHORT_DESC, []() { return DESC; }, { __VA_ARGS__ }); \
#undef BINDING_NAME
#undef BINDING_SHORT_DESC
#undef BINDING_LONG_DESC
#undef BINDING_EXAMPLE
#undef BINDING_SEE_ALSO
#define BINDING_NAME(NAME) static \
mlpack::bindings::markdown::ProgramNameWrapper \
io_programname_dummy_object = \
mlpack::bindings::markdown::ProgramNameWrapper( \
MARKDOWN_BINDING_NAME, NAME);
#define BINDING_SHORT_DESC(SHORT_DESC) static \
mlpack::bindings::markdown::ShortDescriptionWrapper \
io_programshort_desc_dummy_object = \
mlpack::bindings::markdown::ShortDescriptionWrapper( \
MARKDOWN_BINDING_NAME, SHORT_DESC);
#define BINDING_LONG_DESC(LONG_DESC) static \
mlpack::bindings::markdown::LongDescriptionWrapper \
io_programlong_desc_dummy_object = \
mlpack::bindings::markdown::LongDescriptionWrapper( \
MARKDOWN_BINDING_NAME, []() { return std::string(LONG_DESC); });
#ifdef __COUNTER__
#define BINDING_EXAMPLE(EXAMPLE) static \
mlpack::bindings::markdown::ExampleWrapper \
JOIN(io_programexample_dummy_object_, __COUNTER__) = \
mlpack::bindings::markdown::ExampleWrapper(MARKDOWN_BINDING_NAME, \
[]() { return(std::string(EXAMPLE)); });
#define BINDING_SEE_ALSO(DESCRIPTION, LINK) static \
mlpack::bindings::markdown::SeeAlsoWrapper \
JOIN(io_programsee_also_dummy_object_, __COUNTER__) = \
mlpack::bindings::markdown::SeeAlsoWrapper(MARKDOWN_BINDING_NAME, \
DESCRIPTION, LINK);
#else
#define BINDING_EXAMPLE(EXAMPLE) static \
mlpack::bindings::markdown::ExampleWrapper \
JOIN(JOIN(io_programexample_dummy_object_, __LINE__), opt) = \
mlpack::bindings::markdown::ExampleWrapper(MARKDOWN_BINDING_NAME, \
[]() { return(std::string(EXAMPLE)); });
#define BINDING_SEE_ALSO(DESCRIPTION, LINK) static \
mlpack::bindings::markdown::SeeAlsoWrapper \
JOIN(JOIN(io_programsee_also_dummy_object_, __LINE__), opt) = \
mlpack::bindings::markdown::SeeAlsoWrapper(MARKDOWN_BINDING_NAME, \
DESCRIPTION, LINK);
#endif
PARAM_FLAG("verbose", "Display informational messages and the full list of "
"parameters and timers at the end of execution.", "v");
+155 -59
View File
@@ -4,8 +4,8 @@
* @author Ryan Curtin
*
* Definition of PARAM_*_IN() and PARAM_*_OUT() macros, as well as the
* PROGRAM_INFO() macro, which are used to define input and output parameters of
* command-line programs and bindings to other languages.
* Documentation related macro, which are used to define input and output
* parameters of command-line programs and bindings to other languages.
*
* 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
@@ -30,6 +30,118 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
} // namespace mlpack
/**
* @cond
* Don't document internal macros.
*/
// These are ugly, but necessary utility functions we must use to generate a
// unique identifier inside of the PARAM() module.
#define JOIN(x, y) JOIN_AGAIN(x, y)
#define JOIN_AGAIN(x, y) x ## y
/** @endcond */
/**
* Specify the program name of a binding. Only one instance of this macro
* should be present in your program! Therefore, use it in the main.cpp
* (or corresponding binding) in your program.
*
* @see mlpack::IO, PARAM_FLAG(), PARAM_INT_IN(), PARAM_DOUBLE_IN(),
* PARAM_STRING_IN(), PARAM_VECTOR_IN(), PARAM_INT_OUT(), PARAM_DOUBLE_OUT(),
* PARAM_VECTOR_OUT(), PARAM_INT_IN_REQ(), PARAM_DOUBLE_IN_REQ(),
* PARAM_STRING_IN_REQ(), PARAM_VECTOR_IN_REQ(), PARAM_INT_OUT_REQ(),
* PARAM_DOUBLE_OUT_REQ(), PARAM_VECTOR_OUT_REQ(), PARAM_STRING_OUT_REQ().
*
* @param NAME Short string representing the name of the program.
*/
#define BINDING_NAME(NAME) static \
mlpack::util::ProgramName \
io_programname_dummy_object = mlpack::util::ProgramName(NAME);
/**
* Specify the short description of a binding. Only one instance of this macro
* should be present in your program! Therefore, use it in the main.cpp
* (or corresponding binding) in your program.
*
* @see mlpack::IO, PARAM_FLAG(), PARAM_INT_IN(), PARAM_DOUBLE_IN(),
* PARAM_STRING_IN(), PARAM_VECTOR_IN(), PARAM_INT_OUT(), PARAM_DOUBLE_OUT(),
* PARAM_VECTOR_OUT(), PARAM_INT_IN_REQ(), PARAM_DOUBLE_IN_REQ(),
* PARAM_STRING_IN_REQ(), PARAM_VECTOR_IN_REQ(), PARAM_INT_OUT_REQ(),
* PARAM_DOUBLE_OUT_REQ(), PARAM_VECTOR_OUT_REQ(), PARAM_STRING_OUT_REQ().
*
* @param SHORT_DESC Short two-sentence description of the program; it should
* describe what the program implements and does, and a quick overview of
* how it can be used and what it should be used for.
*/
#define BINDING_SHORT_DESC(SHORT_DESC) static \
mlpack::util::ShortDescription \
io_programshort_desc_dummy_object = mlpack::util::ShortDescription( \
SHORT_DESC);
/**
* Specify the long description of a binding. Only one instance of this macro
* present in your program! Therefore, use it in the main.cpp
* (or corresponding binding) in your program.
*
* @see mlpack::IO, PARAM_FLAG(), PARAM_INT_IN(), PARAM_DOUBLE_IN(),
* PARAM_STRING_IN(), PARAM_VECTOR_IN(), PARAM_INT_OUT(), PARAM_DOUBLE_OUT(),
* PARAM_VECTOR_OUT(), PARAM_INT_IN_REQ(), PARAM_DOUBLE_IN_REQ(),
* PARAM_STRING_IN_REQ(), PARAM_VECTOR_IN_REQ(), PARAM_INT_OUT_REQ(),
* PARAM_DOUBLE_OUT_REQ(), PARAM_VECTOR_OUT_REQ(), PARAM_STRING_OUT_REQ().
*
* @param LONG_DESC Long string describing what the program does. Newlines
* should not be used here; this is taken care of by IO (however, you
* can explicitly specify newlines to denote new paragraphs). You can
* also use printing macros like PRINT_PARAM_STRING(), PRINT_DATASET(),
* and others.
*/
#define BINDING_LONG_DESC(LONG_DESC) static \
mlpack::util::LongDescription \
io_programlong_desc_dummy_object = mlpack::util::LongDescription( \
[]() { return std::string(LONG_DESC); });
/**
* Specify the example of a binding. Mutiple instance of this macro can be
* present in your program! Therefore, use it in the main.cpp
* (or corresponding binding) in your program.
*
* @see mlpack::IO, PARAM_FLAG(), PARAM_INT_IN(), PARAM_DOUBLE_IN(),
* PARAM_STRING_IN(), PARAM_VECTOR_IN(), PARAM_INT_OUT(), PARAM_DOUBLE_OUT(),
* PARAM_VECTOR_OUT(), PARAM_INT_IN_REQ(), PARAM_DOUBLE_IN_REQ(),
* PARAM_STRING_IN_REQ(), PARAM_VECTOR_IN_REQ(), PARAM_INT_OUT_REQ(),
* PARAM_DOUBLE_OUT_REQ(), PARAM_VECTOR_OUT_REQ(), PARAM_STRING_OUT_REQ().
*
* @param EXAMPLE Long string describing a simple usage example.. Newlines
* should not be used here; this is taken care of by IO (however, you
* can explicitly specify newlines to denote new paragraphs). You can
* also use printing macros like PRINT_CALL(), PRINT_DATASET(),
* and others.
*/
#ifdef __COUNTER__
#define BINDING_EXAMPLE(EXAMPLE) static \
mlpack::util::Example \
JOIN(io_programexample_dummy_object_, __COUNTER__) = \
mlpack::util::Example( \
[]() { return(std::string(EXAMPLE)); });
#else
#define BINDING_EXAMPLE(EXAMPLE) static \
mlpack::util::Example \
JOIN(JOIN(io_programexample_dummy_object_, __LINE__), opt) = \
mlpack::util::Example( \
[]() { return(std::string(EXAMPLE)); });
#endif
/**
* Specify the see-also of a binding. Mutiple instance of this macro can be
* present in your program! Therefore, use it in the main.cpp
* (or corresponding binding) in your program.
*
* @see mlpack::IO, PARAM_FLAG(), PARAM_INT_IN(), PARAM_DOUBLE_IN(),
* PARAM_STRING_IN(), PARAM_VECTOR_IN(), PARAM_INT_OUT(), PARAM_DOUBLE_OUT(),
* PARAM_VECTOR_OUT(), PARAM_INT_IN_REQ(), PARAM_DOUBLE_IN_REQ(),
* PARAM_STRING_IN_REQ(), PARAM_VECTOR_IN_REQ(), PARAM_INT_OUT_REQ(),
* PARAM_DOUBLE_OUT_REQ(), PARAM_VECTOR_OUT_REQ(), PARAM_STRING_OUT_REQ().
*
* Provide a link for a binding's "see also" documentation section, which is
* primarily (but not necessarily exclusively) used by the Markdown bindings
* This link can be specified by calling SEE_ALSO("description", "link"), where
@@ -42,36 +154,17 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* - A link to a Doxygen page, using the mangled Doxygen name after a
* '\@doxygen/', i.e., "@doxygen/mlpack1_1_adaboost1_1_AdaBoost".
*/
#define SEE_ALSO(DESCRIPTION, LINK) {DESCRIPTION, LINK}
/**
* Document an executable. Only one instance of this macro should be
* present in your program! Therefore, use it in the main.cpp
* (or corresponding executable) in your program.
*
* @see mlpack::IO, PARAM_FLAG(), PARAM_INT_IN(), PARAM_DOUBLE_IN(),
* PARAM_STRING_IN(), PARAM_VECTOR_IN(), PARAM_INT_OUT(), PARAM_DOUBLE_OUT(),
* PARAM_VECTOR_OUT(), PARAM_INT_IN_REQ(), PARAM_DOUBLE_IN_REQ(),
* PARAM_STRING_IN_REQ(), PARAM_VECTOR_IN_REQ(), PARAM_INT_OUT_REQ(),
* PARAM_DOUBLE_OUT_REQ(), PARAM_VECTOR_OUT_REQ(), PARAM_STRING_OUT_REQ().
*
* @param NAME Short string representing the name of the program.
* @param SHORT_DESC Short two-sentence description of the program; it should
* describe what the program implements and does, and a quick overview of
* how it can be used and what it should be used for.
* @param DESC Long string describing what the program does and possibly a
* simple usage example. Newlines should not be used here; this is taken
* care of by IO (however, you can explicitly specify newlines to denote
* new paragraphs). You can also use printing macros like
* PRINT_PARAM_STRING(), PRINT_DATASET(), and others.
* @param ... A set of SEE_ALSO() macros that are used for generating
* documentation. See the SEE_ALSO() macro. This is a varargs argument, so
* you can add as many SEE_ALSO()s as you like.
*/
#define PROGRAM_INFO(NAME, SHORT_DESC, DESC, ...) \
static mlpack::util::ProgramDoc \
io_programdoc_dummy_object = mlpack::util::ProgramDoc(NAME, SHORT_DESC, \
[]() { return DESC; }, { __VA_ARGS__ } )
#ifdef __COUNTER__
#define BINDING_SEE_ALSO(DESCRIPTION, LINK) static \
mlpack::util::SeeAlso \
JOIN(io_programsee_also_dummy_object_, __COUNTER__) = \
mlpack::util::SeeAlso(DESCRIPTION, LINK);
#else
#define BINDING_SEE_ALSO(DESCRIPTION, LINK) static \
mlpack::util::SeeAlso \
JOIN(JOIN(io_programsee_also_dummy_object_, __LINE__), opt) = \
mlpack::util::SeeAlso(DESCRIPTION, LINK);
#endif
/**
* Define a flag parameter.
@@ -82,7 +175,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* here---it will cause problems.
* @param ALIAS An alias for the parameter (one letter).
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -108,7 +202,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* @param ALIAS An alias for the parameter (one letter).
* @param DEF Default value of the parameter.
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
// Use a forward declaration of the class.
@@ -139,7 +234,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
* here---it will cause problems.
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -165,7 +261,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* @param ALIAS An alias for the parameter (one letter).
* @param DEF Default value of the parameter.
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -195,7 +292,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
* here---it will cause problems.
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -213,7 +311,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
*
* The parameter can then be specified on the command line with
* --ID=value. If ALIAS is equal to DEF_MOD (which is set using the
* PROGRAM_INFO() macro), the parameter can be specified with just --ID=value.
* BINDING_LONG_DESC() macro), the parameter can be specified with just
* --ID=value.
*
* @param ID Name of the parameter.
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
@@ -222,7 +321,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* @param ALIAS An alias for the parameter (one letter).
* @param DEF Default value of the parameter.
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -253,7 +353,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* here---it will cause problems.
* @param ALIAS An alias for the parameter (one letter).
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -827,7 +928,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* here---it will cause problems.
* @param ALIAS An alias for the parameter (one letter).
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -860,7 +962,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* here---it will cause problems.
* @param ALIAS An alias for the parameter (one letter).
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -899,7 +1002,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* here---it will cause problems.
* @param ALIAS One-character string representing the alias of the parameter.
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -1011,7 +1115,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* here---it will cause problems.
* @param ALIAS An alias for the parameter (one letter).
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -1035,7 +1140,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* here---it will cause problems.
* @param ALIAS An alias for the parameter (one letter).
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -1059,7 +1165,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* here---it will cause problems.
* @param ALIAS An alias for the parameter (one letter).
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -1085,7 +1192,8 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* here---it will cause problems.
* @param ALIAS An alias for the parameter (one letter).
*
* @see mlpack::IO, PROGRAM_INFO()
* @see mlpack::IO, BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC(),
* BINDING_EXAMPLE() and BINDING_SEE_ALSO().
*
* @bug
* The __COUNTER__ variable is used in most cases to guarantee a unique global
@@ -1098,18 +1206,6 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
#define PARAM_VECTOR_IN_REQ(T, ID, DESC, ALIAS) \
PARAM_IN(std::vector<T>, ID, DESC, ALIAS, std::vector<T>(), true);
/**
* @cond
* Don't document internal macros.
*/
// These are ugly, but necessary utility functions we must use to generate a
// unique identifier inside of the PARAM() module.
#define JOIN(x, y) JOIN_AGAIN(x, y)
#define JOIN_AGAIN(x, y) x ## y
/** @endcond */
/**
* Define an input parameter. Don't use this function; use the other ones above
* that call it. Note that we are using the __LINE__ macro for naming these
+59 -24
View File
@@ -1,9 +1,10 @@
/**
* @file core/util/program_doc.cpp
* @author Yashwant Singh Parihar
* @author Ryan Curtin
*
* Implementation of the ProgramDoc class. The class registers itself with IO
* when constructed.
* Implementation of mutiple classes that store information related to a binding.
* The classes register themselves with IO when constructed.
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
@@ -20,36 +21,70 @@ using namespace mlpack::util;
using namespace std;
/**
* Construct a ProgramDoc object. When constructed, it will register itself
* Construct a ProgramName object. When constructed, it will register itself
* with IO. A fatal error will be thrown if more than one is constructed.
*
* @param defaultModule Name of the default module.
* @param shortDocumentation A short two-sentence description of the program,
* what it does, and what it is useful for.
* @param documentation Long string containing documentation on how to use the
* program and what it is. No newline characters are necessary; this is
* taken care of by IO later.
* @param seeAlso A set of pairs of strings with useful "see also"
* information; each pair is <description, url>.
* @param programName Name of the binding.
*/
ProgramDoc::ProgramDoc(
const std::string programName,
const std::string shortDocumentation,
const std::function<std::string()> documentation,
const std::vector<std::pair<std::string, std::string>> seeAlso) :
programName(std::move(programName)),
shortDocumentation(std::move(shortDocumentation)),
documentation(std::move(documentation)),
seeAlso(std::move(seeAlso))
ProgramName::ProgramName(const std::string& programName)
{
// Register this with IO.
IO::RegisterProgramDoc(this);
IO::GetSingleton().doc.programName = std::move(programName);
}
/**
* Construct an empty ProgramDoc object.
* Construct a ShortDescription object. When constructed, it will register
* itself with IO. A fatal error will be thrown if more than one is
* constructed.
*
* @param shortDescription A short two-sentence description of the binding,
* what it does, and what it is useful for.
*/
ProgramDoc::ProgramDoc()
ShortDescription::ShortDescription(const std::string& shortDescription)
{
IO::RegisterProgramDoc(this);
// Register this with IO.
IO::GetSingleton().doc.shortDescription = std::move(shortDescription);
}
/**
* Construct a LongDescription object. When constructed, it will register itself
* with IO. A fatal error will be thrown if more than one is constructed.
*
* @param longDescription Long string containing documentation on
* what it is. No newline characters are necessary; this is
* taken care of by IO later.
*/
LongDescription::LongDescription(
const std::function<std::string()>& longDescription)
{
// Register this with IO.
IO::GetSingleton().doc.longDescription = std::move(longDescription);
}
/**
* Construct a Example object. When constructed, it will register itself
* with IO.
*
* @param example Documentation on how to use the binding.
*/
Example::Example(
const std::function<std::string()>& example)
{
// Register this with IO.
IO::GetSingleton().doc.example.push_back(std::move(example));
}
/**
* Construct a SeeAlso object. When constructed, it will register itself
* with IO.
*
* @param description Description of SeeAlso.
* @param link Link of SeeAlso.
*/
SeeAlso::SeeAlso(
const std::string& description, const std::string& link)
{
// Register this with IO.
IO::GetSingleton().doc.seeAlso.push_back(std::move(
make_pair(description, link)));
}
+57 -36
View File
@@ -1,8 +1,10 @@
/**
* @file core/util/program_doc.hpp
* @author Yashwant Singh Parihar
* @author Matthew Amidon
*
* The structure used to store a program's name and documentation.
* Implementation of mutiple classes that store information related to a binding.
* The classes register themselves with IO when constructed.
*
* 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
@@ -15,50 +17,69 @@
namespace mlpack {
namespace util {
/**
* A static object whose constructor registers program documentation with the
* IO class. This should not be used outside of IO itself, and you should use
* the PROGRAM_INFO() macro to declare these objects. Only one ProgramDoc
* object should ever exist.
*
* @see core/util/io.hpp, mlpack::IO
*/
class ProgramDoc
class ProgramName
{
public:
/**
* Construct a ProgramDoc object. When constructed, it will register itself
* with IO, and when the user calls --help (or whatever the option is named
* for the given binding type), the given function that returns a std::string
* will be returned.
* Construct a ProgramName object. When constructed, it will register itself
* with IO. A fatal error will be thrown if more than one is constructed.
*
* @param programName Short string representing the name of the program.
* @param shortDocumentation A short two-sentence description of the program,
* what it does, and what it is useful for.
* @param documentation Long string containing documentation on how to use the
* program and what it is. No newline characters are necessary; this is
* taken care of by IO later.
* @param seeAlso A set of pairs of strings with useful "see also"
* information; each pair is <description, url>.
* @param programName Name of the binding.
*/
ProgramDoc(const std::string programName,
const std::string shortDocumentation,
const std::function<std::string()> documentation,
const std::vector<std::pair<std::string, std::string>> seeAlso);
ProgramName(const std::string& programName);
};
class ShortDescription
{
public:
/**
* Construct an empty ProgramDoc object. (This is not meant to be used!)
* Construct a ShortDescription object. When constructed, it will register
* itself with IO. A fatal error will be thrown if more than one is
* constructed.
*
* @param shortDescription A short two-sentence description of the binding,
* what it does, and what it is useful for.
*/
ProgramDoc();
ShortDescription(const std::string& shortDescription);
};
//! The name of the program.
std::string programName;
//! The short documentation for the program.
std::string shortDocumentation;
//! Documentation for what the program does.
std::function<std::string()> documentation;
//! Set of see also information.
std::vector<std::pair<std::string, std::string>> seeAlso;
class LongDescription
{
public:
/**
* Construct a LongDescription object. When constructed, it will register itself
* with IO. A fatal error will be thrown if more than one is constructed.
*
* @param longDescription Long string containing documentation on
* what it is. No newline characters are necessary; this is
* taken care of by IO later.
*/
LongDescription(const std::function<std::string()>& longDescription);
};
class Example
{
public:
/**
* Construct a Example object. When constructed, it will register itself
* with IO.
*
* @param example Documentation on how to use the binding.
*/
Example(const std::function<std::string()>& example);
};
class SeeAlso
{
public:
/**
* Construct a SeeAlso object. When constructed, it will register itself
* with IO.
*
* @param description Description of SeeAlso.
* @param link Link of SeeAlso.
*/
SeeAlso(const std::string& description, const std::string& link);
};
} // namespace util
+24 -15
View File
@@ -46,13 +46,18 @@ using namespace mlpack::tree;
using namespace mlpack::perceptron;
using namespace mlpack::util;
PROGRAM_INFO("AdaBoost",
// Short description.
// Program Name.
BINDING_NAME("AdaBoost");
// Short description.
BINDING_SHORT_DESC(
"An implementation of the AdaBoost.MH (Adaptive Boosting) algorithm for "
"classification. This can be used to train an AdaBoost model on labeled "
"data or use an existing AdaBoost model to predict the classes of new "
"points.",
// Long description.
"points.");
// Long description.
BINDING_LONG_DESC(
"This program implements the AdaBoost (or Adaptive "
"Boosting) algorithm. The variant of AdaBoost implemented here is "
"AdaBoost.MH. It uses a weak learner, either decision stumps or "
@@ -86,8 +91,10 @@ PROGRAM_INFO("AdaBoost",
"."
"\n"
"Use " + PRINT_PARAM_STRING("predictions") + " instead of " +
PRINT_PARAM_STRING("output") + '.' +
"\n\n"
PRINT_PARAM_STRING("output") + '.');
// Example.
BINDING_EXAMPLE(
"For example, to run AdaBoost on an input dataset " +
PRINT_DATASET("data") + " with labels " + PRINT_DATASET("labels") +
"and perceptrons as the weak learner type, storing the trained model in " +
@@ -102,15 +109,17 @@ PROGRAM_INFO("AdaBoost",
PRINT_DATASET("predictions") + " with the following command: "
"\n\n" +
PRINT_CALL("adaboost", "input_model", "model", "test", "test_data",
"predictions", "predictions"),
// See also...
SEE_ALSO("AdaBoost on Wikipedia", "https://en.wikipedia.org/wiki/AdaBoost"),
SEE_ALSO("Improved boosting algorithms using confidence-rated predictions "
"(pdf)", "http://rob.schapire.net/papers/SchapireSi98.pdf"),
SEE_ALSO("Perceptron", "#perceptron"),
SEE_ALSO("Decision Stump", "#decision_stump"),
SEE_ALSO("mlpack::adaboost::AdaBoost C++ class documentation",
"@doxygen/classmlpack_1_1adaboost_1_1AdaBoost.html"));
"predictions", "predictions"));
// See also...
BINDING_SEE_ALSO("AdaBoost on Wikipedia", "https://en.wikipedia.org/wiki/"
"AdaBoost");
BINDING_SEE_ALSO("Improved boosting algorithms using confidence-rated "
"predictions (pdf)", "http://rob.schapire.net/papers/SchapireSi98.pdf");
BINDING_SEE_ALSO("Perceptron", "#perceptron");
BINDING_SEE_ALSO("Decision Stump", "#decision_stump");
BINDING_SEE_ALSO("mlpack::adaboost::AdaBoost C++ class documentation",
"@doxygen/classmlpack_1_1adaboost_1_1AdaBoost.html");
// Input for training.
PARAM_MATRIX_IN("training", "Dataset for training AdaBoost.", "t");
@@ -71,6 +71,8 @@ set(SOURCES
mean_pooling_impl.hpp
minibatch_discrimination.hpp
minibatch_discrimination_impl.hpp
multihead_attention_impl.hpp
multihead_attention.hpp
multiply_constant.hpp
multiply_constant_impl.hpp
multiply_merge.hpp
@@ -79,6 +81,8 @@ set(SOURCES
noisylinear_impl.hpp
parametric_relu.hpp
parametric_relu_impl.hpp
positional_encoding.hpp
positional_encoding_impl.hpp
recurrent.hpp
recurrent_impl.hpp
recurrent_attention.hpp
+3
View File
@@ -44,17 +44,20 @@
#include "leaky_relu.hpp"
#include "linear.hpp"
#include "linear_no_bias.hpp"
#include "linear3d.hpp"
#include "log_softmax.hpp"
#include "lookup.hpp"
#include "lstm.hpp"
#include "max_pooling.hpp"
#include "mean_pooling.hpp"
#include "minibatch_discrimination.hpp"
#include "multihead_attention.hpp"
#include "multiply_constant.hpp"
#include "multiply_merge.hpp"
#include "noisylinear.hpp"
#include "padding.hpp"
#include "parametric_relu.hpp"
#include "positional_encoding.hpp"
#include "recurrent_attention.hpp"
#include "recurrent.hpp"
#include "reinforce_normal.hpp"
+17 -1
View File
@@ -31,8 +31,10 @@
#include <mlpack/methods/ann/layer/c_relu.hpp>
#include <mlpack/methods/ann/layer/flexible_relu.hpp>
#include <mlpack/methods/ann/layer/linear_no_bias.hpp>
#include <mlpack/methods/ann/layer/linear3d.hpp>
#include <mlpack/methods/ann/layer/log_softmax.hpp>
#include <mlpack/methods/ann/layer/lookup.hpp>
#include <mlpack/methods/ann/layer/multihead_attention.hpp>
#include <mlpack/methods/ann/layer/multiply_constant.hpp>
#include <mlpack/methods/ann/layer/max_pooling.hpp>
#include <mlpack/methods/ann/layer/mean_pooling.hpp>
@@ -40,6 +42,7 @@
#include <mlpack/methods/ann/layer/adaptive_max_pooling.hpp>
#include <mlpack/methods/ann/layer/adaptive_mean_pooling.hpp>
#include <mlpack/methods/ann/layer/parametric_relu.hpp>
#include <mlpack/methods/ann/layer/positional_encoding.hpp>
#include <mlpack/methods/ann/layer/reinforce_normal.hpp>
#include <mlpack/methods/ann/layer/reparametrization.hpp>
#include <mlpack/methods/ann/layer/select.hpp>
@@ -96,6 +99,11 @@ template<typename InputDataType,
typename OutputDataType>
class NoisyLinear;
template<typename InputDataType,
typename OutputDataType,
typename RegularizerType>
class Linear3D;
template<typename InputDataType,
typename OutputDataType
>
@@ -106,6 +114,11 @@ template<typename InputDataType,
>
class MiniBatchDiscrimination;
template <typename InputDataType,
typename OutputDataType,
typename RegularizerType>
class MultiheadAttention;
template<typename InputDataType,
typename OutputDataType
>
@@ -205,8 +218,10 @@ template <typename InputDataType,
class AdaptiveMeanPooling;
using MoreTypes = boost::variant<
Linear3D<arma::mat, arma::mat, NoRegularizer>*,
Glimpse<arma::mat, arma::mat>*,
Highway<arma::mat, arma::mat>*,
MultiheadAttention<arma::mat, arma::mat, NoRegularizer>*,
Recurrent<arma::mat, arma::mat>*,
RecurrentAttention<arma::mat, arma::mat>*,
ReinforceNormal<arma::mat, arma::mat>*,
@@ -218,7 +233,8 @@ using MoreTypes = boost::variant<
VRClassReward<arma::mat, arma::mat>*,
VirtualBatchNorm<arma::mat, arma::mat>*,
RBF<arma::mat, arma::mat, GaussianFunction>*,
BaseLayer<GaussianFunction, arma::mat, arma::mat>*
BaseLayer<GaussianFunction, arma::mat, arma::mat>*,
PositionalEncoding<arma::mat, arma::mat>*
>;
template <typename... CustomLayers>
+183
View File
@@ -0,0 +1,183 @@
/**
* @file methods/ann/layer/linear3d.hpp
* @author Mrityunjay Tripathi
*
* Definition of the Linear layer class which accepts 3D input.
*
* 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_LINEAR3D_HPP
#define MLPACK_METHODS_ANN_LAYER_LINEAR3D_HPP
#include <mlpack/prereqs.hpp>
#include <mlpack/methods/ann/layer/layer_types.hpp>
#include <mlpack/methods/ann/regularizer/no_regularizer.hpp>
namespace mlpack {
namespace ann /** Artificial Neural Network. */ {
/**
* Implementation of the Linear3D layer class. The Linear class represents a
* single layer of a neural network.
*
* Shape of input : (inSize * nPoints, batchSize)
* Shape of output : (outSize * nPoints, batchSize)
*
* @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,
typename RegularizerType = NoRegularizer
>
class Linear3D
{
public:
//! Create the Linear3D object.
Linear3D();
/**
* Create the Linear3D layer object using the specified number of units.
*
* @param inSize The number of input units.
* @param outSize The number of output units.
* @param regularizer The regularizer to use, optional.
*/
Linear3D(const size_t inSize,
const size_t outSize,
RegularizerType regularizer = RegularizerType());
/*
* Reset the layer parameter.
*/
void Reset();
/**
* 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 eT>
void Forward(const arma::Mat<eT>& input, arma::Mat<eT>& output);
/**
* Ordinary feed backward pass of a neural network, calculating the function
* f(x) by propagating x backwards trough 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);
/*
* Calculate the gradient using the output delta and the input activation.
*
* @param input The input parameter used for calculating the gradient.
* @param error The calculated error.
* @param gradient The calculated gradient.
*/
template<typename eT>
void Gradient(const arma::Mat<eT>& input,
const arma::Mat<eT>& error,
arma::Mat<eT>& gradient);
//! Get the parameters.
OutputDataType const& Parameters() const { return weights; }
//! Modify the parameters.
OutputDataType& Parameters() { return weights; }
//! Get the input parameter.
InputDataType const& InputParameter() const { return inputParameter; }
//! Modify the input parameter.
InputDataType& InputParameter() { return inputParameter; }
//! Get the output parameter.
OutputDataType const& OutputParameter() const { return outputParameter; }
//! Modify the output parameter.
OutputDataType& OutputParameter() { return outputParameter; }
//! Get the delta.
OutputDataType const& Delta() const { return delta; }
//! Modify the delta.
OutputDataType& Delta() { return delta; }
//! Get the input size.
size_t InputSize() const { return inSize; }
//! Get the output size.
size_t OutputSize() const { return outSize; }
//! Get the gradient.
OutputDataType const& Gradient() const { return gradient; }
//! Modify the gradient.
OutputDataType& Gradient() { return gradient; }
//! Get the weight of the layer.
OutputDataType const& Weight() const { return weight; }
//! Modify the weight of the layer.
OutputDataType& Weight() { return weight; }
//! Get the bias of the layer.
OutputDataType const& Bias() const { return bias; }
//! Modify the bias weights of the layer.
OutputDataType& Bias() { return bias; }
/**
* Serialize the layer
*/
template<typename Archive>
void serialize(Archive& ar, const unsigned int /* version */);
private:
//! Locally-stored number of input units.
size_t inSize;
//! Locally-stored number of output units.
size_t outSize;
//! Locally-stored weight object.
OutputDataType weights;
//! Locally-stored weight parameters.
OutputDataType weight;
//! Locally-stored bias term parameters.
OutputDataType bias;
//! Locally-stored delta object.
OutputDataType delta;
//! Locally-stored gradient object.
OutputDataType gradient;
//! Locally-stored input parameter object.
InputDataType inputParameter;
//! Locally-stored output parameter object.
OutputDataType outputParameter;
//! Locally-stored regularizer object.
RegularizerType regularizer;
}; // class Linear
} // namespace ann
} // namespace mlpack
// Include implementation.
#include "linear3d_impl.hpp"
#endif
@@ -0,0 +1,178 @@
/**
* @file methods/ann/layer/linear3d_impl.hpp
* @author Mrityunjay Tripathi
*
* Implementation of the Linear layer class which accepts 3D input.
*
* 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_LINEAR3D_IMPL_HPP
#define MLPACK_METHODS_ANN_LAYER_LINEAR3D_IMPL_HPP
// In case it hasn't yet been included.
#include "linear3d.hpp"
namespace mlpack {
namespace ann /** Artificial Neural Network. */ {
template<typename InputDataType, typename OutputDataType,
typename RegularizerType>
Linear3D<InputDataType, OutputDataType, RegularizerType>::Linear3D() :
inSize(0),
outSize(0)
{
// Nothing to do here.
}
template<typename InputDataType, typename OutputDataType,
typename RegularizerType>
Linear3D<InputDataType, OutputDataType, RegularizerType>::Linear3D(
const size_t inSize,
const size_t outSize,
RegularizerType regularizer) :
inSize(inSize),
outSize(outSize),
regularizer(regularizer)
{
weights.set_size(outSize * inSize + outSize, 1);
}
template<typename InputDataType, typename OutputDataType,
typename RegularizerType>
void Linear3D<InputDataType, OutputDataType, RegularizerType>::Reset()
{
typedef typename arma::Mat<typename OutputDataType::elem_type> MatType;
weight = MatType(weights.memptr(), outSize, inSize, false, false);
bias = MatType(weights.memptr() + weight.n_elem, outSize, 1, false, false);
}
template<typename InputDataType, typename OutputDataType,
typename RegularizerType>
template<typename eT>
void Linear3D<InputDataType, OutputDataType, RegularizerType>::Forward(
const arma::Mat<eT>& input, arma::Mat<eT>& output)
{
typedef typename arma::Mat<eT> MatType;
typedef typename arma::Cube<eT> CubeType;
if (input.n_rows % inSize != 0)
{
Log::Fatal << "Number of features in the input must be divisible by inSize."
<< std::endl;
}
const size_t nPoints = input.n_rows / inSize;
const size_t batchSize = input.n_cols;
output.set_size(outSize * nPoints, batchSize);
const CubeType inputTemp(const_cast<MatType&>(input).memptr(), inSize,
nPoints, batchSize, false, false);
for (size_t i = 0; i < batchSize; ++i)
{
// Shape of weight : (outSize, inSize).
// Shape of inputTemp : (inSize, nPoints, batchSize).
MatType z = weight * inputTemp.slice(i);
z.each_col() += bias;
output.col(i) = arma::vectorise(z);
}
}
template<typename InputDataType, typename OutputDataType,
typename RegularizerType>
template<typename eT>
void Linear3D<InputDataType, OutputDataType, RegularizerType>::Backward(
const arma::Mat<eT>& /* input */,
const arma::Mat<eT>& gy,
arma::Mat<eT>& g)
{
typedef typename arma::Mat<eT> MatType;
typedef typename arma::Cube<eT> CubeType;
if (gy.n_rows % outSize != 0)
{
Log::Fatal << "Number of rows in propagated error must be divisible by \
outSize." << std::endl;
}
const size_t nPoints = gy.n_rows / outSize;
const size_t batchSize = gy.n_cols;
const CubeType gyTemp(const_cast<MatType&>(gy).memptr(), outSize,
nPoints, batchSize, false, false);
g.set_size(inSize * nPoints, batchSize);
for (size_t i = 0; i < gyTemp.n_slices; ++i)
{
// Shape of weight : (outSize, inSize).
// Shape of gyTemp : (outSize, nPoints, batchSize).
g.col(i) = arma::vectorise(weight.t() * gyTemp.slice(i));
}
}
template<typename InputDataType, typename OutputDataType,
typename RegularizerType>
template<typename eT>
void Linear3D<InputDataType, OutputDataType, RegularizerType>::Gradient(
const arma::Mat<eT>& input,
const arma::Mat<eT>& error,
arma::Mat<eT>& gradient)
{
typedef typename arma::Mat<eT> MatType;
typedef typename arma::Cube<eT> CubeType;
if (error.n_rows % outSize != 0)
Log::Fatal << "Propagated error matrix has invalid dimension!" << std::endl;
const size_t nPoints = input.n_rows / inSize;
const size_t batchSize = input.n_cols;
const CubeType inputTemp(const_cast<MatType&>(input).memptr(), inSize,
nPoints, batchSize, false, false);
const CubeType errorTemp(const_cast<MatType&>(error).memptr(), outSize,
nPoints, batchSize, false, false);
CubeType dW(outSize, inSize, batchSize);
for (size_t i = 0; i < batchSize; ++i)
{
// Shape of errorTemp : (outSize, nPoints, batchSize).
// Shape of inputTemp : (inSize, nPoints, batchSize).
dW.slice(i) = errorTemp.slice(i) * inputTemp.slice(i).t();
}
gradient.set_size(arma::size(weights));
gradient.submat(0, 0, weight.n_elem - 1, 0)
= arma::vectorise(arma::sum(dW, 2));
gradient.submat(weight.n_elem, 0, weights.n_elem - 1, 0)
= arma::vectorise(arma::sum(arma::sum(errorTemp, 2), 1));
regularizer.Evaluate(weights, gradient);
}
template<typename InputDataType, typename OutputDataType,
typename RegularizerType>
template<typename Archive>
void Linear3D<InputDataType, OutputDataType, RegularizerType>::serialize(
Archive& ar, const unsigned int /* version */)
{
ar & BOOST_SERIALIZATION_NVP(inSize);
ar & BOOST_SERIALIZATION_NVP(outSize);
// This is inefficient, but we have to allocate this memory so that
// WeightSetVisitor gets the right size.
if (Archive::is_loading::value)
weights.set_size(outSize * inSize + outSize, 1);
}
} // namespace ann
} // namespace mlpack
#endif
+1 -1
View File
@@ -27,7 +27,7 @@ namespace ann /* Artificial Neural Network. */ {
* the embeddings of those tokens.
*
* The input shape : (sequenceLength, batchSize).
* The output shape : (sequenceLength * embeddingSize, batchSize).
* The output shape : (embeddingSize, sequenceLength, batchSize).
*
* @tparam InputDataType Type of the input data (arma::colvec, arma::mat,
* arma::sp_mat or arma::cube).
+9 -10
View File
@@ -26,7 +26,7 @@ Lookup<InputDataType, OutputDataType>::Lookup(
vocabSize(vocabSize),
embeddingSize(embeddingSize)
{
weights.set_size(vocabSize, embeddingSize);
weights.set_size(embeddingSize, vocabSize);
}
template<typename InputDataType, typename OutputDataType>
@@ -37,15 +37,14 @@ void Lookup<InputDataType, OutputDataType>::Forward(
const size_t seqLength = input.n_rows;
const size_t batchSize = input.n_cols;
output.set_size(seqLength * embeddingSize, batchSize);
output.set_size(embeddingSize * seqLength, batchSize);
for (size_t i = 0; i < batchSize; ++i)
{
//! ith column of output is a vectorized form of a matrix of shape
//! (seqLength, embeddingSize) selected as a combination of rows from the
//! weights. The MultiheadAttention class requires this particular ordering
//! of matrix dimensions.
output.col(i) = arma::vectorise(weights.rows(
// ith column of output is a vectorized form of a matrix of shape
// (embeddingSize, seqLength) selected as a combination of columns from the
// weights.
output.col(i) = arma::vectorise(weights.cols(
arma::conv_to<arma::uvec>::from(input.col(i)) - 1));
}
}
@@ -71,14 +70,14 @@ void Lookup<InputDataType, OutputDataType>::Gradient(
const size_t batchSize = input.n_cols;
arma::Cube<eT> errorTemp(const_cast<arma::Mat<eT>&>(error).memptr(),
seqLength, embeddingSize, batchSize, false, false);
embeddingSize, seqLength, batchSize, false, false);
gradient.set_size(arma::size(weights));
gradient.zeros();
for (size_t i = 0; i < batchSize; ++i)
{
gradient.rows(arma::conv_to<arma::uvec>::from(input.col(i)) - 1)
gradient.cols(arma::conv_to<arma::uvec>::from(input.col(i)) - 1)
+= errorTemp.slice(i);
}
}
@@ -94,7 +93,7 @@ void Lookup<InputDataType, OutputDataType>::serialize(
// This is inefficient, but we have to allocate this memory so that
// WeightSetVisitor gets the right size.
if (Archive::is_loading::value)
weights.set_size(vocabSize, embeddingSize);
weights.set_size(embeddingSize, vocabSize);
}
} // namespace ann
@@ -0,0 +1,267 @@
/**
* @file methods/ann/layer/multihead_attention.hpp
* @author Mrityunjay Tripathi
*
* Definition of the MultiheadAttention class.
*
* @code
* @article{NIPS'17,
* author = {Ashish Vaswani, Llion Jones, Noam Shazeer, Niki Parmar,
* Aidan N. Gomez, Jakob Uszkoreit, Łukasz Kaiser,
* Illia Polosukhin},
* title = {Attention Is All You Need},
* year = {2017},
* url = {http://arxiv.org/abs/1706.03762v5}
* }
* @endcode
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_METHODS_ANN_LAYER_MULTIHEAD_ATTENTION_HPP
#define MLPACK_METHODS_ANN_LAYER_MULTIHEAD_ATTENTION_HPP
#include <mlpack/prereqs.hpp>
#include <mlpack/methods/ann/layer/softmax.hpp>
#include <mlpack/methods/ann/layer/dropout.hpp>
#include <mlpack/methods/ann/init_rules/glorot_init.hpp>
#include <mlpack/methods/ann/regularizer/no_regularizer.hpp>
namespace mlpack {
namespace ann /** Artificial Neural Network. */ {
/**
* Multihead Attention allows the model to jointly attend to information from
* different representation subspaces at different positions. With a single
* attention head, averaging inhibits this. [arxiv.org:1706.03762v5]
*
* The MultiheadAttention class takes concatenated form of query, key and value.
* The query, key and value are concatenated into single matrix and fed to the
* Forward function as input.
*
* The query, key and value are matrices of shapes
* `(embedDim * tgtSeqLen, batchSize)`, `(embedDim * srcSeqLen, batchSize)`
* and `(embedDim * srcSeqLen, batchSize)` respectively. The output is a matrix
* of shape `(embedDim * tgtSeqLen, batchSize)`. The embeddings are stored
* consequently.
*
* @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).
* @tparam RegularizerType Type of the regularizer to be used.
*/
template <
typename InputDataType = arma::mat,
typename OutputDataType = arma::mat,
typename RegularizerType = NoRegularizer
>
class MultiheadAttention
{
public:
/**
* Default constructor.
*/
MultiheadAttention();
/**
* Create the MultiheadAttention object using the specified modules.
*
* @param tgtSeqLen Target sequence length.
* @param srcSeqLen Source sequence length.
* @param embedDim Total dimension of the model.
* @param numHeads Number of parallel attention heads.
*/
MultiheadAttention(const size_t tgtSeqLen,
const size_t srcSeqLen,
const size_t embedDim,
const size_t numHeads);
/**
* Reset the layer parameters.
*/
void Reset();
/**
* Ordinary feed forward pass of a neural network, evaluating the function
* f(x) by propagating the activity forward through f.
*
* @param input The query matrix.
* @param output Resulting output activation.
*/
template<typename eT>
void Forward(const arma::Mat<eT>& input, arma::Mat<eT>& output);
/**
* Ordinary feed backward pass of a neural network, calculating the function
* f(x) by propagating x backwards trough f. Using the results from the feed
* forward pass.
*
* @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);
/**
* Calculate the gradient using the output delta and the input activation.
*
* @param input The input data used for evaluating specified function.
* @param error The calculated error.
* @param gradient The calculated gradient.
*/
template<typename eT>
void Gradient(const arma::Mat<eT>& input,
const arma::Mat<eT>& error,
arma::Mat<eT>& gradient);
/**
* Serialize the layer.
*/
template<typename Archive>
void serialize(Archive& ar, const unsigned int /* version */);
//! Get the target sequence length.
size_t TgtSeqLen() const { return tgtSeqLen; }
//! Modify the target sequence length.
size_t& TgtSeqLen() { return tgtSeqLen; }
//! Get the source sequence length.
size_t SrcSeqLen() const { return srcSeqLen; }
//! Modify the source sequence length.
size_t& SrcSeqLen() { return srcSeqLen; }
//! Get the embedding dimension.
size_t EmbedDim() const { return embedDim; }
//! Modify the embedding dimension.
size_t& EmbedDim() { return embedDim; }
//! Get the number of attention heads.
size_t NumHeads() const { return numHeads; }
//! Modify the number of attention heads.
size_t& NumHeads() { return numHeads; }
//! Get the two dimensional Attention Mask.
OutputDataType const& AttentionMask() const { return attnMask; }
//! Modify the two dimensional Attention Mask.
OutputDataType& AttentionMask() { return attnMask; }
//! Get Key Padding Mask.
OutputDataType const& KeyPaddingMask() const { return keyPaddingMask; }
//! Modify the Key Padding Mask.
OutputDataType& KeyPaddingMask() { return keyPaddingMask; }
//! Get the output parameter.
OutputDataType const& OutputParameter() const { return outputParameter; }
//! Modify the output parameter.
OutputDataType& OutputParameter() { return outputParameter; }
//! Get the delta.
OutputDataType const& Delta() const { return delta; }
//! Modify the delta.
OutputDataType& Delta() { return delta; }
//! Get the gradient.
OutputDataType const& Gradient() const { return grad; }
//! Modify the gradient.
OutputDataType& Gradient() { return grad; }
//! Get the parameters.
OutputDataType const& Parameters() const { return weights; }
//! Modify the parameters.
OutputDataType& Parameters() { return weights; }
private:
//! Element Type of the input.
typedef typename OutputDataType::elem_type ElemType;
//! Target sequence length.
size_t tgtSeqLen;
//! Source sequence lenght.
size_t srcSeqLen;
//! Locally-stored module output size.
size_t embedDim;
//! Locally-stored number of parallel attention heads.
size_t numHeads;
//! Dimensionality of each head.
size_t headDim;
//! Two dimensional Attention Mask of shape (tgtSeqLen, srcSeqLen).
OutputDataType attnMask;
//! Key Padding Mask.
OutputDataType keyPaddingMask;
//! Locally-stored weight matrix associated with query.
OutputDataType queryWt;
//! Locally-stored weight matrix associated with key.
OutputDataType keyWt;
//! Locally-stored weight matrix associated with value.
OutputDataType valueWt;
//! Locally-stored weight matrix associated with attnWt.
OutputDataType outWt;
//! Locally-stored bias associated with query.
OutputDataType qBias;
//! Locally-stored bias associated with key.
OutputDataType kBias;
//! Locall-stored bias associated with value.
OutputDataType vBias;
//! Locally-stored bias associated with attnWt.
OutputDataType outBias;
//! Locally-stored weights parameter.
OutputDataType weights;
//! Locally-stored projected query matrix over linear layer.
arma::Cube<ElemType> qProj;
//! Locally-stored projected key matrix over linear layer.
arma::Cube<ElemType> kProj;
//! Locally-stored projected value matrix over linear layer.
arma::Cube<ElemType> vProj;
//! Locally-stored result of output of dropout layer.
arma::Cube<ElemType> scores;
//! Locally-stored attention output weight to be fed to last linear layer.
arma::Cube<ElemType> attnOut;
//! Softmax layer to represent the probabilities of next sequence.
Softmax<InputDataType, OutputDataType> softmax;
//! Locally-stored delta object.
OutputDataType delta;
//! Locally-stored gradient.
OutputDataType grad;
//! Locally-stored output parameter.
OutputDataType outputParameter;
//! Locally-stored regularizer object.
RegularizerType regularizer;
}; // class MultiheadAttention
} // namespace ann
} // namespace mlpack
// Include implementation.
#include "multihead_attention_impl.hpp"
#endif
@@ -0,0 +1,454 @@
/**
* @file methods/ann/layer/multihead_attention_impl.hpp
* @author Mrityunjay Tripathi
*
* Implementation of the MultiheadAttention 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_MULTIHEAD_ATTENTION_IMPL_HPP
#define MLPACK_METHODS_ANN_LAYER_MULTIHEAD_ATTENTION_IMPL_HPP
// In case it hasn't yet been included.
#include "multihead_attention.hpp"
#include <mlpack/core/math/multiply_slices.hpp>
namespace mlpack {
namespace ann /** Artificial Neural Network. */ {
template <typename InputDataType, typename OutputDataType,
typename RegularizerType>
MultiheadAttention<InputDataType, OutputDataType, RegularizerType>::
MultiheadAttention() :
tgtSeqLen(0),
srcSeqLen(0),
embedDim(0),
numHeads(0),
headDim(0)
{
// Nothing to do here.
}
template <typename InputDataType, typename OutputDataType,
typename RegularizerType>
MultiheadAttention<InputDataType, OutputDataType, RegularizerType>::
MultiheadAttention(
const size_t tgtSeqLen,
const size_t srcSeqLen,
const size_t embedDim,
const size_t numHeads) :
tgtSeqLen(tgtSeqLen),
srcSeqLen(srcSeqLen),
embedDim(embedDim),
numHeads(numHeads)
{
if (embedDim % numHeads != 0)
{
Log::Fatal << "Embedding dimension must be divisible by number of \
attention heads." << std::endl;
}
headDim = embedDim / numHeads;
weights.set_size(4 * (embedDim + 1) * embedDim, 1);
}
template <typename InputDataType, typename OutputDataType,
typename RegularizerType>
void MultiheadAttention<InputDataType, OutputDataType, RegularizerType>::
Reset()
{
typedef typename arma::Mat<typename OutputDataType::elem_type> MatType;
queryWt = MatType(weights.memptr(), embedDim, embedDim, false, false);
keyWt = MatType(weights.memptr() + embedDim * embedDim,
embedDim, embedDim, false, false);
valueWt = MatType(weights.memptr() + 2 * embedDim * embedDim,
embedDim, embedDim, false, false);
outWt = MatType(weights.memptr() + 3 * embedDim * embedDim,
embedDim, embedDim, false, false);
qBias = MatType(weights.memptr()
+ 4 * embedDim * embedDim, embedDim, 1, false, false);
kBias = MatType(weights.memptr()
+ (4 * embedDim + 1) * embedDim, embedDim, 1, false, false);
vBias = MatType(weights.memptr()
+ (4 * embedDim + 2) * embedDim, embedDim, 1, false, false);
outBias = MatType(weights.memptr()
+ (4 * embedDim + 3) * embedDim, 1, embedDim, false, false);
}
template <typename InputDataType, typename OutputDataType,
typename RegularizerType>
template <typename eT>
void MultiheadAttention<InputDataType, OutputDataType, RegularizerType>::
Forward(const arma::Mat<eT>& input, arma::Mat<eT>& output)
{
typedef typename arma::Cube<eT> CubeType;
if (input.n_rows != embedDim * (tgtSeqLen + 2 * srcSeqLen))
{
Log::Fatal << "Incorrect input dimensions!" << std::endl;
}
const size_t batchSize = input.n_cols;
// shape of output : (embedDim * tgtSeqLen, batchSize).
output.set_size(embedDim * tgtSeqLen, batchSize);
// Reshape the input, the query, and the key into a cube from a matrix.
// The shape of q : (embedDim, tgtSeqLen, batchSize).
// The shape of k : (embedDim, srcSeqLen, batchSize).
// The shape of v : (embedDim, srcSeqLen, batchSize).
const CubeType q(const_cast<arma::Mat<eT>&>(input).memptr(),
embedDim, tgtSeqLen, batchSize, false, false);
const CubeType k(const_cast<arma::Mat<eT>&>(input).memptr() +
embedDim * tgtSeqLen * batchSize,
embedDim, srcSeqLen, batchSize, false, false);
const CubeType v(const_cast<arma::Mat<eT>&>(input).memptr() +
embedDim * (tgtSeqLen + srcSeqLen) * batchSize,
embedDim, srcSeqLen, batchSize, false, false);
// qProj, kProj, and vProj are the linearly projected query, key and value
// respectively.
qProj.set_size(tgtSeqLen, embedDim, batchSize);
kProj.set_size(srcSeqLen, embedDim, batchSize);
vProj.set_size(srcSeqLen, embedDim, batchSize);
for (size_t i = 0; i < batchSize; ++i)
{
qProj.slice(i) = arma::trans(
queryWt * q.slice(i) + arma::repmat(qBias, 1, tgtSeqLen));
kProj.slice(i) = arma::trans(
keyWt * k.slice(i) + arma::repmat(kBias, 1, srcSeqLen));
vProj.slice(i) = arma::trans(
valueWt * v.slice(i) + arma::repmat(vBias, 1, srcSeqLen));
}
// The scaling factor sqrt(headDim) is used to prevent exploding values
// after dot product i.e. when qProj is multiplied with kProj.
qProj /= std::sqrt(headDim);
// Split the qProj, kProj and vProj into n heads. That's what Multihead
// Attention is.
qProj.reshape(tgtSeqLen, headDim, numHeads * batchSize);
kProj.reshape(srcSeqLen, headDim, numHeads * batchSize);
vProj.reshape(srcSeqLen, headDim, numHeads * batchSize);
// Calculate the scores i.e. perform the matrix multiplication operation
// on qProj and kProj. Here score = qProj . kProj'
scores = math::MultiplyCube2Cube(qProj, kProj, false, true);
// Apply the attention mask if provided. The attention mask is used to black-
// out future sequences and generally used in Encoder-Decoder attention.
// The attention mask has elements 0 or -infinity.
// The shape of the attention mask : (tgtSeqLen, srcSeqLen).
if (!attnMask.is_empty())
{
if (attnMask.n_rows != tgtSeqLen || attnMask.n_cols != srcSeqLen)
Log::Fatal << "The size of the 'attn_mask' is not correct.\n";
scores.each_slice() += attnMask;
}
// Apply the key padding mask when provided. It blacks-out any particular
// word in the sequence.
// The key padding mask has elements 0 or -infinity.
// The shape of keyPaddingMask : (1, srcSeqLen).
if (!keyPaddingMask.is_empty())
{
if (keyPaddingMask.n_rows != 1 || keyPaddingMask.n_cols != srcSeqLen)
Log::Fatal << "The size of the 'keyPaddingMask' is not correct.\n";
scores.each_slice() += arma::repmat(keyPaddingMask, tgtSeqLen, 1);
}
for (size_t i = 0; i < numHeads * batchSize; ++i)
{
softmax.Forward(scores.slice(i), softmax.OutputParameter());
scores.slice(i) = softmax.OutputParameter();
}
// Calculate the attention output i.e. matrix multiplication of softmax
// output and vProj.
// The shape of attnOutput : (tgtSeqLen, headDim, numHeads * batchSize).
attnOut = math::MultiplyCube2Cube(scores, vProj, false, false);
// Now we will concatenate output of all the heads i.e. we will reshape
// attnOut to (tgtSeqLen, embedDim, batchSize).
attnOut.reshape(tgtSeqLen, embedDim, batchSize);
// The final output is the linear projection of attention output.
for (size_t i = 0; i < batchSize; ++i)
{
output.col(i) = arma::vectorise(arma::trans(attnOut.slice(i) * outWt
+ arma::repmat(outBias, tgtSeqLen, 1)));
}
}
template <typename InputDataType, typename OutputDataType,
typename RegularizerType>
template <typename eT>
void MultiheadAttention<InputDataType, OutputDataType, RegularizerType>::
Backward(const arma::Mat<eT>& /* input */,
const arma::Mat<eT>& gy,
arma::Mat<eT>& g)
{
typedef typename arma::Cube<eT> CubeType;
if (gy.n_rows != tgtSeqLen * embedDim)
{
Log::Fatal << "Backpropagated error has incorrect dimensions!" << std::endl;
}
const size_t batchSize = gy.n_cols;
g.set_size(embedDim * (tgtSeqLen + 2 * srcSeqLen), batchSize);
// Reshape the propagated gradient into a cube.
// The shape of gyTemp : (tgtSeqLen, embedDim, batchSize).
// We need not split it into n heads now because this is the part when
// output were concatenated from n heads.
CubeType gyTemp(const_cast<arma::Mat<eT>&>(gy).memptr(), embedDim,
tgtSeqLen, batchSize, true, false);
// The shape of gyTemp : (embedDim, tgtSeqLen, batchSize).
// The shape of outWt : (embedDim, embedDim).
// The shape of the result : (tgtSeqLen, embedDim, batchSize).
gyTemp = math::MultiplyCube2Mat(gyTemp, outWt, true, true);
// Now since the shape of gyTemp is (tgtSeqLen, embedDim, batchSize). We will
// split it into n heads.
// The shape of gyTemp : (tgtSeqLen, headDim, numHeads * batchSize).
gyTemp.reshape(tgtSeqLen, headDim, numHeads * batchSize);
// Obtain backpropagted error of value.
// Shape of gyTemp : (tgtSeqLen, headDim, numHeads * batchSize).
// Shape of scores : (tgtSeqLen, srcSeqLen, numHeads * batchSize).
// The shape of tmp : (srcSeqLen, headDim, numHeads * batchSize).
CubeType tmp = math::MultiplyCube2Cube(scores, gyTemp, true, false);
// Concatenate results of all the attention heads.
tmp.reshape(srcSeqLen, embedDim, batchSize);
for (size_t i = 0; i < batchSize; ++i)
{
g.submat((tgtSeqLen + srcSeqLen) * embedDim, i, g.n_rows - 1, i)
= arma::vectorise(arma::trans(tmp.slice(i) * valueWt));
}
// The shape of gyTemp : (tgtSeqLen, headDim, numHeads * batchSize).
// The shape of vProj : (srcSeqLen, headDim, numHeads * batchSize).
// So the new shape of gyTemp : (tgtSeqLen, srcSeqLen, numHeads * batchSize).
gyTemp = math::MultiplyCube2Cube(gyTemp, vProj, false, true);
for (size_t i = 0; i < numHeads * batchSize; ++i)
{
// We will perform backpropagation of softmax over each slice of gyTemp.
softmax.Backward(scores.slice(i), gyTemp.slice(i), gyTemp.slice(i));
}
// Obtain backpropagated error of key.
// The shape of qProj : (tgtSeqLen, headDim, numHeads * batchSize).
// The shape of gyTemp : (tgtSeqLen, srcSeqLen, numHeads * batchSize).
// The new shape of tmp : (srcSeqLen, headDim, numHeads * batchSize).
tmp = math::MultiplyCube2Cube(gyTemp, qProj, true, false);
// Concatenate results of all the attention heads.
tmp.reshape(srcSeqLen, embedDim, batchSize);
for (size_t i = 0; i < batchSize; ++i)
{
g.submat(tgtSeqLen * embedDim, i, (tgtSeqLen + srcSeqLen) * embedDim - 1, i)
= arma::vectorise(arma::trans(tmp.slice(i) * keyWt));
}
// Obtain backpropagated error of the query.
// The shape of kProj : (srcSeqLen, headDim, numHeads * batchSize).
// The shape of gyTemp : (tgtSeqLen, srcSeqLen, numHeads * batchSize).
// The new shape of tmp : (tgtSeqLen, headDim, numHeads * batchSize).
tmp = math::MultiplyCube2Cube(gyTemp, kProj) / std::sqrt(headDim);
// Concatenate results of all the attention heads.
tmp.reshape(tgtSeqLen, embedDim, batchSize);
for (size_t i = 0; i < batchSize; ++i)
{
g.submat(0, i, tgtSeqLen * embedDim - 1, i)
= arma::vectorise(arma::trans(tmp.slice(i) * queryWt));
}
}
template <typename InputDataType, typename OutputDataType,
typename RegularizerType>
template <typename eT>
void MultiheadAttention<InputDataType, OutputDataType, RegularizerType>::
Gradient(const arma::Mat<eT>& input,
const arma::Mat<eT>& error,
arma::Mat<eT>& gradient)
{
typedef typename arma::Cube<eT> CubeType;
typedef typename arma::Mat<eT> MatType;
if (input.n_rows != embedDim * (tgtSeqLen + 2 * srcSeqLen))
{
Log::Fatal << "Incorrect input dimensions!" << std::endl;
}
if (error.n_rows != tgtSeqLen * embedDim)
{
Log::Fatal << "Backpropagated error has incorrect dimensions." << std::endl;
}
const size_t batchSize = input.n_cols;
const size_t wtSize = embedDim * embedDim;
// The shape of gradient : (4 * embedDim * embedDim + 4 * embedDim, 1).
gradient.set_size(arma::size(weights));
const CubeType q(const_cast<MatType&>(input).memptr(),
embedDim, tgtSeqLen, batchSize, false, false);
const CubeType k(const_cast<MatType&>(input).memptr() + q.n_elem,
embedDim, srcSeqLen, batchSize, false, false);
const CubeType v(const_cast<MatType&>(input).memptr() + q.n_elem + k.n_elem,
embedDim, srcSeqLen, batchSize, false, false);
// Reshape the propagated error into a cube.
// The shape of errorTemp : (embedDim, tgtSeqLen, batchSize).
CubeType errorTemp(const_cast<arma::Mat<eT>&>(error).memptr(), embedDim,
tgtSeqLen, batchSize, true, false);
// Gradient wrt. outBias, i.e. dL/d(outBias).
gradient.rows(4 * wtSize + 3 * embedDim, 4 * wtSize + 4 * embedDim - 1)
= arma::vectorise(arma::sum(arma::sum(errorTemp, 2), 1));
// The shape of attnOut : (tgtSeqLen, embedDim, batchSize).
// The shape of errorTemp : (embedDim, tgtSeqLen, batchSize).
// The shape of gyTemp : (embedDim, embedDim, batchSize).
CubeType gyTemp = math::MultiplyCube2Cube(attnOut, errorTemp, true, true);
// Gradient wrt. outWt, i.e. dL/d(outWt). We will take sum of gyTemp along
// the slices and vectorise the output.
gradient.rows(3 * wtSize, 4 * wtSize - 1)
= arma::vectorise(arma::sum(gyTemp, 2));
// Partial derivative wrt. attnOut.
// The shape of outWt : (embedDim, embedDim).
// The shape of errorTemp : (embedDim, tgtSeqLen, batchSize).
// The shape of gyTemp : (tgtSeqLen, embedDim, batchSize).
gyTemp = math::MultiplyCube2Mat(errorTemp, outWt, true, true);
// Now we will split it into n heads i.e. reshape it into a cube of shape
// (tgtSeqLen, headDim, numHeads * batchSize).
gyTemp.reshape(tgtSeqLen, headDim, numHeads * batchSize);
// Shape of gyTemp : (tgtSeqLen, headDim, numHeads * batchSize).
// Shape of scores : (tgtSeqLen, srcSeqLen, numHeads * batchSize).
// The new shape of errorTemp : (srcSeqLen, headDim, numHeads * batchSize).
errorTemp = math::MultiplyCube2Cube(scores, gyTemp, true, false);
// Now we will concatenate the propagated errors from all heads i.e. we
// will reshape errorTemp to (srcSeqLen, embedDim, batchSize).
errorTemp.reshape(srcSeqLen, embedDim, batchSize);
// Gradient wrt. vBias, i.e. dL/d(vBias). We will take summation of errorTemp
// over all the batches and over all the sequences.
gradient.rows(4 * wtSize + 2 * embedDim, 4 * wtSize + 3 * embedDim - 1)
= arma::vectorise(arma::sum(arma::sum(errorTemp, 2), 0));
// Shape of v : (srcSeqLen, embedDim, batchSize).
// Shape of errorTemp : (srcSeqLen, embedDim, bathSize).
// The new shape of errorTemp : (embedDim, embedDim, batchSize).
errorTemp = math::MultiplyCube2Cube(errorTemp, v, true, true);
// Gradient wrt. valueWt, i.e. dL/d(valueWt). We will take summation over all
// batches of errorTemp.
gradient.rows(2 * wtSize, 3 * wtSize - 1)
= arma::vectorise(arma::sum(errorTemp, 2));
// Now, the shape of gyTemp : (tgtSeqLen, headDim, numHeads * batchSize).
// The shape of vProj : (srcSeqLen, headDim, numHeads * batchSize).
// The new shape of errorTemp : (tgtSeqLen, srcSeqLen, numHeads * batchSize).
errorTemp = math::MultiplyCube2Cube(gyTemp, vProj, false, true);
for (size_t i = 0; i < numHeads * batchSize; ++i)
{
// The shape of scores : (tgtSeqLen, srcSeqLen, numHeads * batchSize).
// The shape of errorTemp : (tgtSeqLen, srcSeqLen, numHeads * batchSize).
// The new shape of errorTemp remain same.
softmax.Backward(scores.slice(i), errorTemp.slice(i), errorTemp.slice(i));
}
// The shape of qProj : (tgtSeqLen, headDim, numHeads * batchSize).
// The shape of errorTemp : (tgtSeqLen, srcSeqLen, numHeads * batchSize).
// The shape of gyTemp : (srcSeqLen, headDim, numHeads * batchSize).
gyTemp = math::MultiplyCube2Cube(errorTemp, qProj, true, false);
// We will now conctenate the propagated errors from all heads.
// The new shape of gyTemp : (srcSeqLen, embedDim, batchSize).
gyTemp.reshape(srcSeqLen, embedDim, batchSize);
// Gradient wrt. kBias, i.e. dL/d(kBias). We will take summation over all the
// batches of gyTemp and then over all the sequences.
gradient.rows(4 * wtSize + embedDim, 4 * wtSize + 2 * embedDim - 1)
= arma::vectorise(arma::sum(arma::sum(gyTemp, 2), 0));
// The shape of k : (embedDim, srcSeqLen, batchSize).
// The shape of gyTemp : (srcSeqLen, embedDim, batchSize).
// The shape of dkeyWt : (embedDim, embedDim, batchSize).
gyTemp = math::MultiplyCube2Cube(gyTemp, k, true, true);
// Gradient wrt. keyWt, i.e. dL/d(keyWt). We will take summation over all the
// batches of dkeyWt.
gradient.rows(wtSize, 2 * wtSize - 1) = arma::vectorise(arma::sum(gyTemp, 2));
// The shape of kProj : (srcSeqLen, headDim, numHeads * batchSize).
// The shape of errorTemp : (tgtSeqLen, srcSeqLen, numHeads * batchSize).
// The shape of gyTemp : (tgtSeqLen, headDim, numHeads * batchSize).
gyTemp = math::MultiplyCube2Cube(errorTemp, kProj, false, false);
// Now, we will concatenate propagated error of all heads.
gyTemp.reshape(tgtSeqLen, embedDim, batchSize);
gyTemp /= std::sqrt(headDim);
// Gradient wrt. qBias, i.e. dL/d(qBias). We will take summation over all the
// batches of gyTemp and over all the sequences.
gradient.rows(4 * wtSize, 4 * wtSize + embedDim - 1)
= arma::vectorise(arma::sum(arma::sum(gyTemp, 2), 0));
// The shape of gyTemp : (tgtSeqLen, embedDim, batchSize).
// The shape of q : (embedDim, tgtSeqLen, batchSize).
// The shape of gyTemp : (embedDim, embedDim, batchSize).
gyTemp = math::MultiplyCube2Cube(gyTemp, q, true, true);
// Gradient wrt. queryWt, i.e. dL/d(queryBias). We will take summation over
// all the batches of gyTemp.
gradient.rows(0, wtSize - 1) = arma::vectorise(arma::sum(gyTemp, 2));
// Regularize according to the given regularization rule.
regularizer.Evaluate(weights, gradient);
}
template <typename InputDataType, typename OutputDataType,
typename RegularizerType>
template <typename Archive>
void MultiheadAttention<InputDataType, OutputDataType, RegularizerType>::
serialize(Archive& ar, const unsigned int /* version */)
{
ar & BOOST_SERIALIZATION_NVP(tgtSeqLen);
ar & BOOST_SERIALIZATION_NVP(srcSeqLen);
ar & BOOST_SERIALIZATION_NVP(embedDim);
ar & BOOST_SERIALIZATION_NVP(numHeads);
ar & BOOST_SERIALIZATION_NVP(headDim);
// This is inefficient, but we have to allocate this memory so that
// WeightSetVisitor gets the right size.
if (Archive::is_loading::value)
weights.set_size(4 * embedDim * (embedDim + 1), 1);
}
} // namespace ann
} // namespace mlpack
#endif
@@ -0,0 +1,133 @@
/**
* @file methods/ann/layer/positional_encoding.hpp
* @author Mrityunjay Tripathi
*
* Definition of the Positional Encoding.
*
* 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_POSITIONAL_ENCODING_HPP
#define MLPACK_METHODS_ANN_LAYER_POSITIONAL_ENCODING_HPP
#include <mlpack/prereqs.hpp>
namespace mlpack {
namespace ann /** Artificial Neural Network. */ {
/**
* Positional Encoding injects some information about the relative or absolute
* position of the tokens in the sequence.
*
* The input and the output have the same shape:
* `(embedDim * maxSequenceLength, batchSize)`. The embeddings are stored
* consequently.
*
* @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 PositionalEncoding
{
public:
/**
* Create PositionalEncoding object.
*/
PositionalEncoding();
/**
* Create the PositionalEncoding layer object using the specified parameters.
*
* @param embedDim The length of the embedding vector.
* @param maxSequenceLength Number of tokens in each sequence.
*/
PositionalEncoding(const size_t embedDim,
const size_t maxSequenceLength);
/**
* 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 eT>
void Forward(const arma::Mat<eT>& input, arma::Mat<eT>& output);
/**
* Ordinary feed backward pass of a neural network, calculating the function
* f(x) by propagating x backwards trough 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 input parameter.
InputDataType const& InputParameter() const { return inputParameter; }
//! Modify the input parameter.
InputDataType& InputParameter() { return inputParameter; }
//! Get the output parameter.
OutputDataType const& OutputParameter() const { return outputParameter; }
//! Modify the output parameter.
OutputDataType& OutputParameter() { return outputParameter; }
//! Get the delta.
OutputDataType const& Delta() const { return delta; }
//! Modify the delta.
OutputDataType& Delta() { return delta; }
//! Get the positional encoding vector.
InputDataType const& Encoding() const { return positionalEncoding; }
/**
* Serialize the layer
*/
template<typename Archive>
void serialize(Archive& ar, const unsigned int /* version */);
private:
/**
* Initialize positional encodings for further use.
*/
void InitPositionalEncoding();
//! Locally-stored embedding dimension.
size_t embedDim;
//! Locally-stored maximum sequence length that has to be encoded.
size_t maxSequenceLength;
//! Locally-stored positional encodings.
InputDataType positionalEncoding;
//! Locally-stored delta object.
OutputDataType delta;
//! Locally-stored input parameter object.
InputDataType inputParameter;
//! Locally-stored output parameter object.
OutputDataType outputParameter;
}; // class PositionalEncoding
} // namespace ann
} // namespace mlpack
// Include implementation.
#include "positional_encoding_impl.hpp"
#endif
@@ -0,0 +1,90 @@
/**
* @file methods/ann/layer/positional_encoding_impl.hpp
* @author Mrityunjay Tripathi
*
* Implementation of the Positional Encoding.
*
* 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_POSITIONAL_ENCODING_IMPL_HPP
#define MLPACK_METHODS_ANN_LAYER_POSITIONAL_ENCODING_IMPL_HPP
// In case it hasn't yet been included.
#include "positional_encoding.hpp"
namespace mlpack {
namespace ann /** Artificial Neural Network. */ {
template<typename InputDataType, typename OutputDataType>
PositionalEncoding<InputDataType, OutputDataType>::PositionalEncoding() :
embedDim(0),
maxSequenceLength(0)
{
// Nothing to do here.
}
template<typename InputDataType, typename OutputDataType>
PositionalEncoding<InputDataType, OutputDataType>::PositionalEncoding(
const size_t embedDim,
const size_t maxSequenceLength) :
embedDim(embedDim),
maxSequenceLength(maxSequenceLength)
{
InitPositionalEncoding();
}
template<typename InputDataType, typename OutputDataType>
void PositionalEncoding<InputDataType, OutputDataType>::InitPositionalEncoding()
{
positionalEncoding.set_size(maxSequenceLength, embedDim);
const InputDataType position = arma::regspace(0, 1, maxSequenceLength - 1);
const InputDataType divTerm = arma::exp(arma::regspace(0, 2, embedDim - 1)
* (- std::log(10000.0) / embedDim));
const InputDataType theta = position * divTerm.t();
for (size_t i = 0; i < theta.n_cols; ++i)
{
positionalEncoding.col(2 * i) = arma::sin(theta.col(i));
positionalEncoding.col(2 * i + 1) = arma::cos(theta.col(i));
}
positionalEncoding = arma::vectorise(positionalEncoding.t());
}
template<typename InputDataType, typename OutputDataType>
template<typename eT>
void PositionalEncoding<InputDataType, OutputDataType>::Forward(
const arma::Mat<eT>& input, arma::Mat<eT>& output)
{
if (input.n_rows != embedDim * maxSequenceLength)
Log::Fatal << "Incorrect input dimensions!" << std::endl;
output = input.each_col() + positionalEncoding;
}
template<typename InputDataType, typename OutputDataType>
template<typename eT>
void PositionalEncoding<InputDataType, OutputDataType>::Backward(
const arma::Mat<eT>& /* input */, const arma::Mat<eT>& gy, arma::Mat<eT>& g)
{
g = gy;
}
template<typename InputDataType, typename OutputDataType>
template<typename Archive>
void PositionalEncoding<InputDataType, OutputDataType>::serialize(
Archive& ar, const unsigned int /* version */)
{
ar & BOOST_SERIALIZATION_NVP(embedDim);
ar & BOOST_SERIALIZATION_NVP(maxSequenceLength);
if (Archive::is_loading::value)
InitPositionalEncoding();
}
} // namespace ann
} // namespace mlpack
#endif
+36 -36
View File
@@ -70,12 +70,12 @@ class RBM
const bool persistence = false);
// Reset the network.
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
Reset();
// Reset the network.
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
Reset();
@@ -116,9 +116,9 @@ class RBM
*
* @param input The visible neurons.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, double>::type
FreeEnergy(arma::Mat<ElemType>&& input);
FreeEnergy(const arma::Mat<ElemType>& input);
/**
* This function calculates the free energy of the SpikeSlabRBM.
@@ -130,10 +130,10 @@ class RBM
*
* @param input The visible layer neurons.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value,
double>::type
FreeEnergy(arma::Mat<ElemType>&& input);
FreeEnergy(const arma::Mat<ElemType>& input);
/**
* Calculates the gradient of the RBM network on the provided input.
@@ -141,9 +141,9 @@ class RBM
* @param input The provided input data.
* @param gradient Stores the gradient of the RBM network.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
Phase(DataType&& input, DataType&& gradient);
Phase(const InputType& input, DataType& gradient);
/**
* Calculates the gradient of the RBM network on the provided input.
@@ -151,9 +151,9 @@ class RBM
* @param input The provided input data.
* @param gradient Stores the gradient of the RBM network.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
Phase(DataType&& input, DataType&& gradient);
Phase(const InputType& input, DataType& gradient);
/**
* This function samples the hidden layer given the visible layer using
@@ -162,9 +162,9 @@ class RBM
* @param input Visible layer input.
* @param output The sampled hidden layer.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
SampleHidden(arma::Mat<ElemType>&& input, arma::Mat<ElemType>&& output);
SampleHidden(const arma::Mat<ElemType>& input, arma::Mat<ElemType>& output);
/**
* This function samples the slab outputs from the Normal distribution with
@@ -176,9 +176,9 @@ class RBM
* @param input Consists of both visible and spike variables.
* @param output Sampled slab neurons.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
SampleHidden(arma::Mat<ElemType>&& input, arma::Mat<ElemType>&& output);
SampleHidden(const arma::Mat<ElemType>& input, arma::Mat<ElemType>& output);
/**
* This function samples the visible layer given the hidden layer using
@@ -187,9 +187,9 @@ class RBM
* @param input Hidden layer of the network.
* @param output The sampled visible layer.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
SampleVisible(arma::Mat<ElemType>&& input, arma::Mat<ElemType>&& output);
SampleVisible(arma::Mat<ElemType>& input, arma::Mat<ElemType>& output);
/**
* Sample Hidden function samples the slab outputs from the Normal
@@ -201,9 +201,9 @@ class RBM
* @param input Hidden layer of the network.
* @param output The sampled visible layer.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
SampleVisible(arma::Mat<ElemType>&& input, arma::Mat<ElemType>&& output);
SampleVisible(arma::Mat<ElemType>& input, arma::Mat<ElemType>& output);
/**
* The function calculates the mean for the visible layer.
@@ -211,9 +211,9 @@ class RBM
* @param input Hidden neurons from the hidden layer of the network.
* @param output Visible neuron activations.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
VisibleMean(DataType&& input, DataType&& output);
VisibleMean(InputType& input, DataType& output);
/**
* The function calculates the mean of the Normal distribution of P(v|s, h).
@@ -223,9 +223,9 @@ class RBM
* @param input Consists of both the spike and slab variables.
* @param output Mean of the of the Normal distribution.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
VisibleMean(DataType&& input, DataType&& output);
VisibleMean(InputType& input, DataType& output);
/**
* The function calculates the mean for the hidden layer.
@@ -233,9 +233,9 @@ class RBM
* @param input Visible neurons.
* @param output Hidden neuron activations.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
HiddenMean(DataType&& input, DataType&& output);
HiddenMean(const InputType& input, DataType& output);
/**
* The function calculates the mean of the Normal distribution of P(s|v, h).
@@ -247,9 +247,9 @@ class RBM
* @param input Visible layer neurons.
* @param output Consists of both the spike samples and slab samples.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
HiddenMean(DataType&& input, DataType&& output);
HiddenMean(const InputType& input, DataType& output);
/**
* The function calculates the mean of the distribution P(h|v),
@@ -259,18 +259,18 @@ class RBM
* @param visible The visible layer neurons.
* @param spikeMean Indicates P(h|v).
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
SpikeMean(DataType&& visible, DataType&& spikeMean);
SpikeMean(const InputType& visible, DataType& spikeMean);
/**
* The function samples the spike function using Bernoulli distribution.
* @param spikeMean Indicates P(h|v).
* @param spike Sampled binary spike variables.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
SampleSpike(DataType&& spikeMean, DataType&& spike);
SampleSpike(InputType& spikeMean, DataType& spike);
/**
* The function calculates the mean of Normal distribution of P(s|v, h),
@@ -281,9 +281,9 @@ class RBM
* @param spike The spike variables from hidden layer.
* @param slabMean The mean of the Normal distribution of slab neurons.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
SlabMean(DataType&& visible, DataType&& spike, DataType&& slabMean);
SlabMean(const DataType& visible, DataType& spike, DataType& slabMean);
/**
* The function samples from the Normal distribution of P(s|v, h),
@@ -295,9 +295,9 @@ class RBM
* @param slabMean Mean of the Normal distribution of the slab neurons.
* @param slab Sampled slab variable from the Normal distribution.
*/
template<typename Policy = PolicyType>
template<typename Policy = PolicyType, typename InputType = DataType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
SampleSlab(DataType&& slabMean, DataType&& slab);
SampleSlab(InputType& slabMean, DataType& slab);
/**
* This function does the k-step Gibbs Sampling.
@@ -306,8 +306,8 @@ class RBM
* @param output Used for storing the negative sample.
* @param steps Number of Gibbs Sampling steps taken.
*/
void Gibbs(arma::Mat<ElemType>&& input,
arma::Mat<ElemType>&& output,
void Gibbs(const arma::Mat<ElemType>& input,
arma::Mat<ElemType>& output,
const size_t steps = SIZE_MAX);
/**
+40 -38
View File
@@ -58,7 +58,7 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::Reset()
{
@@ -108,10 +108,10 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, double>::type
RBM<InitializationRuleType, DataType, PolicyType>::FreeEnergy(
arma::Mat<ElemType>&& input)
const arma::Mat<ElemType>& input)
{
preActivation = (weight.slice(0) * input);
preActivation.each_col() += hiddenBias;
@@ -124,11 +124,11 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::Phase(
DataType&& input,
DataType&& gradient)
const InputType& input,
DataType& gradient)
{
arma::Cube<ElemType> weightGrad = arma::Cube<ElemType>(gradient.memptr(),
hiddenSize, visibleSize, 1, false, false);
@@ -136,7 +136,7 @@ RBM<InitializationRuleType, DataType, PolicyType>::Phase(
DataType hiddenBiasGrad = DataType(gradient.memptr() + weightGrad.n_elem,
hiddenSize, 1, false, false);
HiddenMean(std::move(input), std::move(hiddenBiasGrad));
HiddenMean(input, hiddenBiasGrad);
weightGrad.slice(0) = hiddenBiasGrad * input.t();
}
@@ -150,10 +150,10 @@ double RBM<InitializationRuleType, DataType, PolicyType>::Evaluate(
const size_t i,
const size_t batchSize)
{
Gibbs(std::move(predictors.cols(i, i + batchSize - 1)),
std::move(negativeSamples));
return std::fabs(FreeEnergy(std::move(predictors.cols(i,
i + batchSize - 1))) - FreeEnergy(std::move(negativeSamples)));
Gibbs(predictors.cols(i, i + batchSize - 1),
negativeSamples);
return std::fabs(FreeEnergy(predictors.cols(i,
i + batchSize - 1)) - FreeEnergy(negativeSamples));
}
template<
@@ -161,13 +161,13 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::SampleHidden(
arma::Mat<ElemType>&& input,
arma::Mat<ElemType>&& output)
const arma::Mat<ElemType>& input,
arma::Mat<ElemType>& output)
{
HiddenMean(std::move(input), std::move(output));
HiddenMean(input, output);
for (size_t i = 0; i < output.n_elem; ++i)
{
@@ -180,13 +180,13 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::SampleVisible(
arma::Mat<ElemType>&& input,
arma::Mat<ElemType>&& output)
arma::Mat<ElemType>& input,
arma::Mat<ElemType>& output)
{
VisibleMean(std::move(input), std::move(output));
VisibleMean(input, output);
for (size_t i = 0; i < output.n_elem; ++i)
{
@@ -199,10 +199,11 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::VisibleMean(DataType&& input,
DataType&& output)
RBM<InitializationRuleType, DataType, PolicyType>::VisibleMean(
InputType& input,
DataType& output)
{
output = weight.slice(0).t() * input;
output.each_col() += visibleBias;
@@ -214,10 +215,11 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, BinaryRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::HiddenMean(DataType&& input,
DataType&& output)
RBM<InitializationRuleType, DataType, PolicyType>::HiddenMean(
const InputType& input,
DataType& output)
{
output = weight.slice(0) * input;
output.each_col() += hiddenBias;
@@ -230,27 +232,27 @@ template<
typename PolicyType
>
void RBM<InitializationRuleType, DataType, PolicyType>::Gibbs(
arma::Mat<ElemType>&& input,
arma::Mat<ElemType>&& output,
const arma::Mat<ElemType>& input,
arma::Mat<ElemType>& output,
const size_t steps)
{
this->steps = (steps == SIZE_MAX) ? this->numSteps : steps;
if (persistence && !state.is_empty())
{
SampleHidden(std::move(state), std::move(gibbsTemporary));
SampleVisible(std::move(gibbsTemporary), std::move(output));
SampleHidden(state, gibbsTemporary);
SampleVisible(gibbsTemporary, output);
}
else
{
SampleHidden(std::move(input), std::move(gibbsTemporary));
SampleVisible(std::move(gibbsTemporary), std::move(output));
SampleHidden(input, gibbsTemporary);
SampleVisible(gibbsTemporary, output);
}
for (size_t j = 1; j < this->steps; ++j)
{
SampleHidden(std::move(output), std::move(gibbsTemporary));
SampleVisible(std::move(gibbsTemporary), std::move(output));
SampleHidden(output, gibbsTemporary);
SampleVisible(gibbsTemporary, output);
}
if (persistence)
{
@@ -272,14 +274,14 @@ void RBM<InitializationRuleType, DataType, PolicyType>::Gradient(
positiveGradient.zeros();
negativeGradient.zeros();
Phase(std::move(predictors.cols(i, i + batchSize - 1)),
std::move(positiveGradient));
Phase(predictors.cols(i, i + batchSize - 1),
positiveGradient);
for (size_t i = 0; i < negSteps; ++i)
{
Gibbs(std::move(predictors.cols(i, i + batchSize - 1)),
std::move(negativeSamples));
Phase(std::move(negativeSamples), std::move(tempNegativeGradient));
Gibbs(predictors.cols(i, i + batchSize - 1),
negativeSamples);
Phase(negativeSamples, tempNegativeGradient);
negativeGradient += tempNegativeGradient;
}
@@ -25,7 +25,7 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::Reset()
{
@@ -65,10 +65,10 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, double>::type
RBM<InitializationRuleType, DataType, PolicyType>::FreeEnergy(
arma::Mat<ElemType>&& input)
const arma::Mat<ElemType>& input)
{
ElemType freeEnergy = 0.5 * visiblePenalty(0) * arma::dot(input, input);
@@ -90,11 +90,11 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::Phase(
DataType&& input,
DataType&& gradient)
const InputType& input,
DataType& gradient)
{
arma::Cube<ElemType> weightGrad = arma::Cube<ElemType>
(gradient.memptr(), visibleSize, poolSize, hiddenSize, false, false);
@@ -102,12 +102,9 @@ RBM<InitializationRuleType, DataType, PolicyType>::Phase(
DataType spikeBiasGrad = DataType(gradient.memptr() + weightGrad.n_elem,
hiddenSize, 1, false, false);
DataType visiblePenaltyGrad = DataType(gradient.memptr() +
weightGrad.n_elem + spikeBiasGrad.n_elem, 1, 1, false, false);
SpikeMean(std::move(input), std::move(spikeMean));
SampleSpike(std::move(spikeMean), std::move(spikeSamples));
SlabMean(std::move(input), std::move(spikeSamples), std::move(slabMean));
SpikeMean(input, spikeMean);
SampleSpike(spikeMean, spikeSamples);
SlabMean(input, spikeSamples, slabMean);
for (size_t i = 0 ; i < hiddenSize; ++i)
{
@@ -116,9 +113,9 @@ RBM<InitializationRuleType, DataType, PolicyType>::Phase(
}
spikeBiasGrad = spikeMean;
visiblePenaltyGrad = -0.5 * arma::dot(input, input)
/ std::pow(input.n_cols, 2);
// Setting visiblePenaltyGrad.
gradient.row(weightGrad.n_elem + spikeBiasGrad.n_elem) = -0.5 * arma::dot(
input, input) / std::pow(input.n_cols, 2);
}
template<
@@ -126,11 +123,11 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::SampleHidden(
arma::Mat<ElemType>&& input,
arma::Mat<ElemType>&& output)
const arma::Mat<ElemType>& input,
arma::Mat<ElemType>& output)
{
output.set_size(hiddenSize + poolSize * hiddenSize, 1);
@@ -138,10 +135,10 @@ RBM<InitializationRuleType, DataType, PolicyType>::SampleHidden(
DataType slab(output.memptr() + hiddenSize, poolSize, hiddenSize, false,
false);
SpikeMean(std::move(input), std::move(spike));
SampleSpike(std::move(spike), std::move(spike));
SlabMean(std::move(input), std::move(spike), std::move(slab));
SampleSlab(std::move(slab), std::move(slab));
SpikeMean(input, spike);
SampleSpike(spike, spike);
SlabMean(input, spike, slab);
SampleSlab(slab, slab);
}
template<
@@ -149,16 +146,16 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::SampleVisible(
arma::Mat<ElemType>&& input,
arma::Mat<ElemType>&& output)
arma::Mat<ElemType>& input,
arma::Mat<ElemType>& output)
{
const size_t numMaxTrials = 10;
size_t k = 0;
VisibleMean(std::move(input), std::move(visibleMean));
VisibleMean(input, visibleMean);
output.set_size(visibleSize, 1);
for (k = 0; k < numMaxTrials; ++k)
@@ -187,11 +184,11 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::VisibleMean(
DataType&& input,
DataType&& output)
InputType& input,
DataType& output)
{
output.zeros(visibleSize, 1);
@@ -212,11 +209,11 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::HiddenMean(
DataType&& input,
DataType&& output)
const InputType& input,
DataType& output)
{
output.set_size(hiddenSize + poolSize * hiddenSize, 1);
@@ -224,9 +221,9 @@ RBM<InitializationRuleType, DataType, PolicyType>::HiddenMean(
DataType slab(output.memptr() + hiddenSize, poolSize, hiddenSize, false,
false);
SpikeMean(std::move(input), std::move(spike));
SampleSpike(std::move(spike), std::move(spikeSamples));
SlabMean(std::move(input), std::move(spikeSamples), std::move(slab));
SpikeMean(input, spike);
SampleSpike(spike, spikeSamples);
SlabMean(input, spikeSamples, slab);
}
template<
@@ -234,11 +231,11 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::SpikeMean(
DataType&& visible,
DataType&& spikeMean)
const InputType& visible,
DataType& spikeMean)
{
for (size_t i = 0; i < hiddenSize; ++i)
{
@@ -253,11 +250,11 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::SampleSpike(
DataType&& spikeMean,
DataType&& spike)
InputType& spikeMean,
DataType& spike)
{
for (size_t i = 0; i < hiddenSize; ++i)
{
@@ -270,12 +267,12 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::SlabMean(
DataType&& visible,
DataType&& spike,
DataType&& slabMean)
const DataType& visible,
DataType& spike,
DataType& slabMean)
{
for (size_t i = 0; i < hiddenSize; ++i)
{
@@ -289,11 +286,11 @@ template<
typename DataType,
typename PolicyType
>
template<typename Policy>
template<typename Policy, typename InputType>
typename std::enable_if<std::is_same<Policy, SpikeSlabRBM>::value, void>::type
RBM<InitializationRuleType, DataType, PolicyType>::SampleSlab(
DataType&& slabMean,
DataType&& slab)
InputType& slabMean,
DataType& slab)
{
for (size_t i = 0; i < hiddenSize; ++i)
{
@@ -21,13 +21,18 @@ using namespace mlpack::neighbor;
using namespace mlpack::util;
using namespace std;
PROGRAM_INFO("Approximate furthest neighbor search",
// Short description.
// Program Name.
BINDING_NAME("Approximate furthest neighbor search");
// Short description.
BINDING_SHORT_DESC(
"An implementation of two strategies for furthest neighbor search. This "
"can be used to compute the furthest neighbor of query point(s) from a set "
"of points; furthest neighbor models can be saved and reused with future "
"query point(s).",
// Long description.
"query point(s).");
// Long description.
BINDING_LONG_DESC(
"This program implements two strategies for furthest neighbor search. "
"These strategies are:"
"\n\n"
@@ -69,8 +74,10 @@ PROGRAM_INFO("Approximate furthest neighbor search",
PRINT_PARAM_STRING("neighbors") + " and " +
PRINT_PARAM_STRING("distances") + " output parameters. Each row of these "
"output matrices holds the k distances or neighbor indices for each query "
"point."
"\n\n"
"point.");
// Example.
BINDING_EXAMPLE(
"For example, to find the 5 approximate furthest neighbors with " +
PRINT_DATASET("reference_set") + " as the reference set and " +
PRINT_DATASET("query_set") + " as the query set using DrusillaSelect, "
@@ -96,18 +103,20 @@ PROGRAM_INFO("Approximate furthest neighbor search",
PRINT_DATASET("neighbors") + " by calling"
"\n\n" +
PRINT_CALL("approx_kfn", "input_model", "model", "query", "new_query_set",
"k", 3, "neighbors", "neighbors"),
SEE_ALSO("k-furthest-neighbor search", "#kfn"),
SEE_ALSO("k-nearest-neighbor search", "#knn"),
SEE_ALSO("Fast approximate furthest neighbors with data-dependent candidate"
" selection (pdf)", "http://ratml.org/pub/pdf/2016fast.pdf"),
SEE_ALSO("Approximate furthest neighbor in high dimensions (pdf)",
"k", 3, "neighbors", "neighbors"));
// See also...
BINDING_SEE_ALSO("k-furthest-neighbor search", "#kfn");
BINDING_SEE_ALSO("k-nearest-neighbor search", "#knn");
BINDING_SEE_ALSO("Fast approximate furthest neighbors with data-dependent"
" candidate selection (pdf)", "http://ratml.org/pub/pdf/2016fast.pdf");
BINDING_SEE_ALSO("Approximate furthest neighbor in high dimensions (pdf)",
"https://pdfs.semanticscholar.org/a4b5/7b9cbf37201fb1d9a56c0f4eefad0466"
"9c20.pdf"),
SEE_ALSO("mlpack::neighbor::QDAFN class documentation",
"@doxygen/classmlpack_1_1neighbor_1_1QDAFN.html"),
SEE_ALSO("mlpack::neighbor::DrusillaSelect class documentation",
"@doxygen/classmlpack_1_1neighbor_1_1DrusillaSelect.html"));
"9c20.pdf");
BINDING_SEE_ALSO("mlpack::neighbor::QDAFN class documentation",
"@doxygen/classmlpack_1_1neighbor_1_1QDAFN.html");
BINDING_SEE_ALSO("mlpack::neighbor::DrusillaSelect class documentation",
"@doxygen/classmlpack_1_1neighbor_1_1DrusillaSelect.html");
PARAM_MATRIX_IN("reference", "Matrix containing the reference dataset.", "r");
PARAM_MATRIX_IN("query", "Matrix containing query points.", "q");
@@ -21,10 +21,15 @@ using namespace mlpack;
using namespace mlpack::regression;
using namespace mlpack::util;
PROGRAM_INFO("BayesianLinearRegression",
// Short description.
"An implementation of the bayesian linear regression.",
// Long description.
// Program Name.
BINDING_NAME("BayesianLinearRegression");
// Short description.
BINDING_SHORT_DESC(
"An implementation of the bayesian linear regression.");
// Long description.
BINDING_LONG_DESC(
"An implementation of the bayesian linear regression."
"\n"
"This model is a probabilistic view and implementation of the linear "
@@ -57,8 +62,10 @@ PROGRAM_INFO("BayesianLinearRegression",
"responses to the test points can be saved with the " +
PRINT_PARAM_STRING("predictions") + " output parameter. The "
"corresponding standard deviation can be save by precising the " +
PRINT_PARAM_STRING("stds") + " parameter."
"\n\n"
PRINT_PARAM_STRING("stds") + " parameter.");
// Example.
BINDING_EXAMPLE(
"For example, the following command trains a model on the data " +
PRINT_DATASET("data") + " and responses " + PRINT_DATASET("responses") +
"with center set to true and scale set to false (so, Bayesian "
@@ -84,15 +91,17 @@ PROGRAM_INFO("BayesianLinearRegression",
"\n\n" +
PRINT_CALL("bayesian_linear_regression", "input_model",
"bayesian_linear_regression_model", "test", "test",
"predictions", "test_predictions", "stds", "stds"),
SEE_ALSO("Bayesian Interpolation",
"https://authors.library.caltech.edu/13792/1/MACnc92a.pdf"),
SEE_ALSO("Bayesian Linear Regression, Section 3.3",
"predictions", "test_predictions", "stds", "stds"));
// See also...
BINDING_SEE_ALSO("Bayesian Interpolation",
"https://authors.library.caltech.edu/13792/1/MACnc92a.pdf");
BINDING_SEE_ALSO("Bayesian Linear Regression, Section 3.3",
"MLA Bishop, Christopher M. Pattern Recognition and Machine "
"Learning. New York :Springer, 2006, section 3.3."),
SEE_ALSO("mlpack::regression::BayesianLinearRegression C++ class "
"Learning. New York :Springer, 2006, section 3.3.");
BINDING_SEE_ALSO("mlpack::regression::BayesianLinearRegression C++ class "
"documentation",
"@doxygen/classmlpack_1_1regression_1_1BayesianLinearRegression.html"));
"@doxygen/classmlpack_1_1regression_1_1BayesianLinearRegression.html");
PARAM_MATRIX_IN("input", "Matrix of covariates (X).", "i");
+29 -20
View File
@@ -41,13 +41,17 @@ using namespace mlpack::svd;
using namespace mlpack::util;
using namespace std;
// Document program.
PROGRAM_INFO("Collaborative Filtering",
// Short description.
// Program Name.
BINDING_NAME("Collaborative Filtering");
// Short description.
BINDING_SHORT_DESC(
"An implementation of several collaborative filtering (CF) techniques for "
"recommender systems. This can be used to train a new CF model, or use an"
" existing CF model to compute recommendations.",
// Long description.
" existing CF model to compute recommendations.");
// Long description.
BINDING_LONG_DESC(
"This program performs collaborative "
"filtering (CF) on the given dataset. Given a list of user, item and "
"preferences (the " + PRINT_PARAM_STRING("training") + " parameter), "
@@ -111,8 +115,10 @@ PROGRAM_INFO("Collaborative Filtering",
" - 'z_score' -- Z-Score Normalization\n"
"\n"
"A trained model may be saved to with the " +
PRINT_PARAM_STRING("output_model") + " output parameter."
"\n\n"
PRINT_PARAM_STRING("output_model") + " output parameter.");
// Example.
BINDING_EXAMPLE(
"To train a CF model on a dataset " + PRINT_DATASET("training_set") + " "
"using NMF for decomposition and saving the trained model to " +
PRINT_MODEL("model") + ", one could call: "
@@ -126,20 +132,23 @@ PROGRAM_INFO("Collaborative Filtering",
"call "
"\n\n" +
PRINT_CALL("cf", "input_model", "model", "query", "users",
"recommendations", 5, "output", "recommendations"),
SEE_ALSO("Collaborative filtering tutorial", "@doxygen/cftutorial.html"),
SEE_ALSO("Alternating Matrix Factorization tutorial",
"@doxygen/amftutorial.html"),
SEE_ALSO("Collaborative Filtering on Wikipedia",
"https://en.wikipedia.org/wiki/Collaborative_filtering"),
SEE_ALSO("Matrix factorization on Wikipedia",
"recommendations", 5, "output", "recommendations"));
// See also...
BINDING_SEE_ALSO("Collaborative filtering tutorial",
"@doxygen/cftutorial.html");
BINDING_SEE_ALSO("Alternating Matrix Factorization tutorial",
"@doxygen/amftutorial.html");
BINDING_SEE_ALSO("Collaborative Filtering on Wikipedia",
"https://en.wikipedia.org/wiki/Collaborative_filtering");
BINDING_SEE_ALSO("Matrix factorization on Wikipedia",
"https://en.wikipedia.org/wiki/Matrix_factorization_"
"(recommender_systems)"),
SEE_ALSO("Matrix factorization techniques for recommender systems (pdf)",
"http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.441.3234"
"&rep=rep1&type=pdf"),
SEE_ALSO("mlpack::cf::CFType class documentation",
"@doxygen/classmlpack_1_1cf_1_1CFType.html"));
"(recommender_systems)");
BINDING_SEE_ALSO("Matrix factorization techniques for recommender systems"
" (pdf)", "http://citeseerx.ist.psu.edu/viewdoc/download?doi="
"10.1.1.441.3234&rep=rep1&type=pdf");
BINDING_SEE_ALSO("mlpack::cf::CFType class documentation",
"@doxygen/classmlpack_1_1cf_1_1CFType.html");
// Parameters for training a model.
PARAM_MATRIX_IN("training", "Input dataset to perform CF on.", "t");
+21 -12
View File
@@ -27,11 +27,16 @@ using namespace mlpack::tree;
using namespace mlpack::util;
using namespace std;
PROGRAM_INFO("DBSCAN clustering",
// Short description.
// Program Name.
BINDING_NAME("DBSCAN clustering");
// Short description.
BINDING_SHORT_DESC(
"An implementation of DBSCAN clustering. Given a dataset, this can "
"compute and return a clustering of that dataset.",
// Long description.
"compute and return a clustering of that dataset.");
// Long description.
BINDING_LONG_DESC(
"This program implements the DBSCAN algorithm for clustering using "
"accelerated tree-based range search. The type of tree that is used "
"may be parameterized, or brute-force range search may also be used."
@@ -58,19 +63,23 @@ PROGRAM_INFO("DBSCAN clustering",
" 'hilbert-r', 'r-plus', 'r-plus-plus', 'cover', 'ball'. The " +
PRINT_PARAM_STRING("single_mode") + " parameter will force single-tree "
"search (as opposed to the default dual-tree search), and '" +
PRINT_PARAM_STRING("naive") + " will force brute-force range search."
"\n\n"
PRINT_PARAM_STRING("naive") + " will force brute-force range search.");
// Example.
BINDING_EXAMPLE(
"An example usage to run DBSCAN on the dataset in " +
PRINT_DATASET("input") + " with a radius of 0.5 and a minimum cluster size"
" of 5 is given below:"
"\n\n" +
PRINT_CALL("dbscan", "input", "input", "epsilon", 0.5, "min_size", 5),
SEE_ALSO("DBSCAN on Wikipedia", "https://en.wikipedia.org/wiki/DBSCAN"),
SEE_ALSO("A density-based algorithm for discovering clusters in large "
PRINT_CALL("dbscan", "input", "input", "epsilon", 0.5, "min_size", 5));
// See also...
BINDING_SEE_ALSO("DBSCAN on Wikipedia", "https://en.wikipedia.org/wiki/DBSCAN");
BINDING_SEE_ALSO("A density-based algorithm for discovering clusters in large "
"spatial databases with noise (pdf)",
"http://www.aaai.org/Papers/KDD/1996/KDD96-037.pdf"),
SEE_ALSO("mlpack::dbscan::DBSCAN class documentation",
"@doxygen/classmlpack_1_1dbscan_1_1DBSCAN.html"));
"http://www.aaai.org/Papers/KDD/1996/KDD96-037.pdf");
BINDING_SEE_ALSO("mlpack::dbscan::DBSCAN class documentation",
"@doxygen/classmlpack_1_1dbscan_1_1DBSCAN.html");
PARAM_MATRIX_IN_REQ("input", "Input dataset to cluster.", "i");
PARAM_UROW_OUT("assignments", "Output matrix for assignments of each "
@@ -21,12 +21,17 @@ using namespace mlpack::util;
using namespace std;
using namespace arma;
PROGRAM_INFO("Decision Stump",
// Short description.
// Program Name.
BINDING_NAME("Decision Stump");
// Short description.
BINDING_SHORT_DESC(
"An implementation of a decision stump, which is a single-level decision "
"tree. Given labeled data, a new decision stump can be trained; or, an "
"existing decision stump can be used to classify points.",
// Long description.
"existing decision stump can be used to classify points.");
// Long description.
BINDING_LONG_DESC(
"This program implements a decision stump, which is a single-level decision"
" tree. The decision stump will split on one dimension of the input data, "
"and will split into multiple buckets. The dimension and bins are selected"
@@ -66,12 +71,14 @@ PROGRAM_INFO("Decision Stump",
"\n\n"
"After training, a decision stump can be saved with the " +
PRINT_PARAM_STRING("output_model") + " output parameter. That stump may "
"later be re-used in subsequent calls to this program (or others).",
SEE_ALSO("Decision tree", "#decision_tree"),
SEE_ALSO("Decision stumps on Wikipedia",
"https://en.wikipedia.org/wiki/Decision_stump"),
SEE_ALSO("mlpack::decision_stump::DecisionStump class documentation",
"@doxygen/classmlpack_1_1decision__stump_1_1DecisionStump.html"));
"later be re-used in subsequent calls to this program (or others).");
// See also...
BINDING_SEE_ALSO("Decision tree", "#decision_tree");
BINDING_SEE_ALSO("Decision stumps on Wikipedia",
"https://en.wikipedia.org/wiki/Decision_stump");
BINDING_SEE_ALSO("mlpack::decision_stump::DecisionStump class documentation",
"@doxygen/classmlpack_1_1decision__stump_1_1DecisionStump.html");
// Datasets we might load.
PARAM_MATRIX_IN("training", "The dataset to train on.", "t");
@@ -20,13 +20,18 @@ using namespace mlpack::tree;
using namespace mlpack::data;
using namespace mlpack::util;
PROGRAM_INFO("Decision tree",
// Short description.
// Program Name.
BINDING_NAME("Decision tree");
// Short description.
BINDING_SHORT_DESC(
"An implementation of an ID3-style decision tree for classification, which"
" supports categorical data. Given labeled data with numeric or "
"categorical features, a decision tree can be trained and saved; or, an "
"existing decision tree can be used for classification on new points.",
// Long description.
"existing decision tree can be used for classification on new points.");
// Long description.
BINDING_LONG_DESC(
"Train and evaluate using a decision tree. Given a dataset containing "
"numeric or categorical features, and associated labels for each point in "
"the dataset, this program can train a decision tree on that data."
@@ -59,8 +64,10 @@ PROGRAM_INFO("Decision tree",
" parameter. Predictions for each test point may be saved via the " +
PRINT_PARAM_STRING("predictions") + " output parameter. Class "
"probabilities for each prediction may be saved with the " +
PRINT_PARAM_STRING("probabilities") + " output parameter."
"\n\n"
PRINT_PARAM_STRING("probabilities") + " output parameter.");
// Example.
BINDING_EXAMPLE(
"For example, to train a decision tree with a minimum leaf size of 20 on "
"the dataset contained in " + PRINT_DATASET("data") + " with labels " +
PRINT_DATASET("labels") + ", saving the output model to " +
@@ -78,15 +85,17 @@ PROGRAM_INFO("Decision tree",
PRINT_DATASET("predictions") + ", one could call "
"\n\n" +
PRINT_CALL("decision_tree", "input_model", "tree", "test", "test_set",
"test_labels", "test_labels", "predictions", "predictions"),
SEE_ALSO("Decision stump", "#decision_stump"),
SEE_ALSO("Random forest", "#random_forest"),
SEE_ALSO("Decision trees on Wikipedia",
"https://en.wikipedia.org/wiki/Decision_tree_learning"),
SEE_ALSO("Induction of Decision Trees (pdf)",
"https://link.springer.com/content/pdf/10.1007/BF00116251.pdf"),
SEE_ALSO("mlpack::tree::DecisionTree class documentation",
"@doxygen/classmlpack_1_1tree_1_1DecisionTree.html"));
"test_labels", "test_labels", "predictions", "predictions"));
// See also...
BINDING_SEE_ALSO("Decision stump", "#decision_stump");
BINDING_SEE_ALSO("Random forest", "#random_forest");
BINDING_SEE_ALSO("Decision trees on Wikipedia",
"https://en.wikipedia.org/wiki/Decision_tree_learning");
BINDING_SEE_ALSO("Induction of Decision Trees (pdf)",
"https://link.springer.com/content/pdf/10.1007/BF00116251.pdf");
BINDING_SEE_ALSO("mlpack::tree::DecisionTree class documentation",
"@doxygen/classmlpack_1_1tree_1_1DecisionTree.html");
// Datasets.
PARAM_MATRIX_AND_INFO_IN("training", "Training dataset (may be categorical).",
+20 -13
View File
@@ -19,12 +19,17 @@ using namespace mlpack::det;
using namespace mlpack::util;
using namespace std;
PROGRAM_INFO("Density Estimation With Density Estimation Trees",
// Short description.
// Program Name.
BINDING_NAME("Density Estimation With Density Estimation Trees");
// Short description.
BINDING_SHORT_DESC(
"An implementation of density estimation trees for the density estimation "
"task. Density estimation trees can be trained or used to predict the "
"density at locations given by query points.",
// Long description.
"density at locations given by query points.");
// Long description.
BINDING_LONG_DESC(
"This program performs a number of functions related to Density Estimation "
"Trees. The optimal Density Estimation Tree (DET) can be trained on a set "
"of data (specified by " + PRINT_PARAM_STRING("training") + ") using "
@@ -54,15 +59,17 @@ PROGRAM_INFO("Density Estimation With Density Estimation Trees",
"trained on the given training points, or a tree given as the parameter " +
PRINT_PARAM_STRING("input_model") + ". The density estimates for the test"
" points may be saved using the " +
PRINT_PARAM_STRING("test_set_estimates") + " output parameter.",
SEE_ALSO("Density estimation tree (DET) tutorial",
"@doxygen/dettutorial.html"),
SEE_ALSO("Density estimation on Wikipedia",
"https://en.wikipedia.org/wiki/Density_estimation"),
SEE_ALSO("Density estimation trees (pdf)",
"http://www.mlpack.org/papers/det.pdf"),
SEE_ALSO("mlpack::tree::DTree class documentation",
"@doxygen/classmlpack_1_1det_1_1DTree.html"));
PRINT_PARAM_STRING("test_set_estimates") + " output parameter.");
// See also...
BINDING_SEE_ALSO("Density estimation tree (DET) tutorial",
"@doxygen/dettutorial.html");
BINDING_SEE_ALSO("Density estimation on Wikipedia",
"https://en.wikipedia.org/wiki/Density_estimation");
BINDING_SEE_ALSO("Density estimation trees (pdf)",
"http://www.mlpack.org/papers/det.pdf");
BINDING_SEE_ALSO("mlpack::tree::DTree class documentation",
"@doxygen/classmlpack_1_1det_1_1DTree.html");
// Input data files.
PARAM_MATRIX_IN("training", "The data set on which to build a density "
+23 -14
View File
@@ -30,11 +30,16 @@
#include "dtb.hpp"
PROGRAM_INFO("Fast Euclidean Minimum Spanning Tree",
// Short description.
// Program Name.
BINDING_NAME("Fast Euclidean Minimum Spanning Tree");
// Short description.
BINDING_SHORT_DESC(
"An implementation of the Dual-Tree Boruvka algorithm for computing the "
"Euclidean minimum spanning tree of a set of input points.",
// Long description.
"Euclidean minimum spanning tree of a set of input points.");
// Long description.
BINDING_LONG_DESC(
"This program can compute the Euclidean minimum spanning tree of a set of "
"input points using the dual-tree Boruvka algorithm."
"\n\n"
@@ -47,8 +52,10 @@ PROGRAM_INFO("Fast Euclidean Minimum Spanning Tree",
"and if the " + PRINT_PARAM_STRING("naive") + " option is given, then "
"brute-force search is used (this is typically much slower in low "
"dimensions). The leaf size does not affect the results, but it may have "
"some effect on the runtime of the algorithm."
"\n\n"
"some effect on the runtime of the algorithm.");
// Example.
BINDING_EXAMPLE(
"For example, the minimum spanning tree of the input dataset " +
PRINT_DATASET("data") + " can be calculated with a leaf size of 20 and "
"stored as " + PRINT_DATASET("spanning_tree") + " using the following "
@@ -60,14 +67,16 @@ PROGRAM_INFO("Fast Euclidean Minimum Spanning Tree",
"The output matrix is a three-dimensional matrix, where each row indicates "
"an edge. The first dimension corresponds to the lesser index of the edge;"
" the second dimension corresponds to the greater index of the edge; and "
"the third column corresponds to the distance between the two points.",
SEE_ALSO("EMST Tutorial", "@doxygen/emst_tutorial.html"),
SEE_ALSO("Minimum spanning tree on Wikipedia",
"https://en.wikipedia.org/wiki/Minimum_spanning_tree"),
SEE_ALSO("Fast Euclidean Minimum Spanning Tree: Algorithm, Analysis, and "
"Applications (pdf)", "http://www.mlpack.org/papers/emst.pdf"),
SEE_ALSO("mlpack::emst::DualTreeBoruvka class documentation",
"@doxygen/classmlpack_1_1emst_1_1DualTreeBoruvka.html"));
"the third column corresponds to the distance between the two points.");
// See also...
BINDING_SEE_ALSO("EMST Tutorial", "@doxygen/emst_tutorial.html");
BINDING_SEE_ALSO("Minimum spanning tree on Wikipedia",
"https://en.wikipedia.org/wiki/Minimum_spanning_tree");
BINDING_SEE_ALSO("Fast Euclidean Minimum Spanning Tree: Algorithm, Analysis,"
" and Applications (pdf)", "http://www.mlpack.org/papers/emst.pdf");
BINDING_SEE_ALSO("mlpack::emst::DualTreeBoruvka class documentation",
"@doxygen/classmlpack_1_1emst_1_1DualTreeBoruvka.html");
PARAM_MATRIX_IN_REQ("input", "Input data matrix.", "i");
PARAM_MATRIX_OUT("output", "Output data. Stored as an edge list.", "o");
+23 -14
View File
@@ -24,20 +24,27 @@ using namespace mlpack::tree;
using namespace mlpack::metric;
using namespace mlpack::util;
PROGRAM_INFO("FastMKS (Fast Max-Kernel Search)",
// Short description.
// Program Name.
BINDING_NAME("FastMKS (Fast Max-Kernel Search)");
// Short description.
BINDING_SHORT_DESC(
"An implementation of the single-tree and dual-tree fast max-kernel search"
" (FastMKS) algorithm. Given a set of reference points and a set of query"
" points, this can find the reference point with maximum kernel value for "
"each query point; trained models can be reused for future queries.",
// Long description.
"each query point; trained models can be reused for future queries.");
// Long description.
BINDING_LONG_DESC(
"This program will find the k maximum kernels of a set of points, "
"using a query set and a reference set (which can optionally be the same "
"set). More specifically, for each point in the query set, the k points in"
" the reference set with maximum kernel evaluations are found. The kernel "
"function used is specified with the " + PRINT_PARAM_STRING("kernel") +
" parameter."
"\n\n"
" parameter.");
// Example.
BINDING_EXAMPLE(
"For example, the following command will calculate, for each point in the "
"query set " + PRINT_DATASET("query") + ", the five points in the "
"reference set " + PRINT_DATASET("reference") + " with maximum kernel "
@@ -57,14 +64,16 @@ PROGRAM_INFO("FastMKS (Fast Max-Kernel Search)",
"\n\n"
"This program performs FastMKS using a cover tree. The base used to build "
"the cover tree can be specified with the " + PRINT_PARAM_STRING("base") +
" parameter.",
SEE_ALSO("Fast max-kernel search tutorial (fastmks)",
"@doxygen/fmkstutorial.html"),
SEE_ALSO("k-nearest-neighbor search", "#knn"),
SEE_ALSO("Dual-tree Fast Exact Max-Kernel Search (pdf)",
"http://mlpack.org/papers/fmks.pdf"),
SEE_ALSO("mlpack::fastmks::FastMKS class documentation",
"@doxygen/classmlpack_1_1fastmks_1_1FastMKS.html"));
" parameter.");
// See also...
BINDING_SEE_ALSO("Fast max-kernel search tutorial (fastmks)",
"@doxygen/fmkstutorial.html");
BINDING_SEE_ALSO("k-nearest-neighbor search", "#knn");
BINDING_SEE_ALSO("Dual-tree Fast Exact Max-Kernel Search (pdf)",
"http://mlpack.org/papers/fmks.pdf");
BINDING_SEE_ALSO("mlpack::fastmks::FastMKS class documentation",
"@doxygen/classmlpack_1_1fastmks_1_1FastMKS.html");
// Model-building parameters.
PARAM_MATRIX_IN("reference", "The reference dataset.", "r");
+22 -13
View File
@@ -19,30 +19,39 @@ using namespace mlpack;
using namespace mlpack::gmm;
using namespace mlpack::util;
PROGRAM_INFO("GMM Sample Generator",
// Short description.
// Program Name.
BINDING_NAME("GMM Sample Generator");
// Short description.
BINDING_SHORT_DESC(
"A sample generator for pre-trained GMMs. Given a pre-trained GMM, this "
"can sample new points randomly from that distribution.",
// Long description.
"can sample new points randomly from that distribution.");
// Long description.
BINDING_LONG_DESC(
"This program is able to generate samples from a pre-trained GMM (use "
"gmm_train to train a GMM). The pre-trained GMM must be specified with "
"the " + PRINT_PARAM_STRING("input_model") + " parameter. The number "
"of samples to generate is specified by the " +
PRINT_PARAM_STRING("samples") + " parameter. Output samples may be "
"saved with the " + PRINT_PARAM_STRING("output") + " output parameter."
"\n\n"
"saved with the " + PRINT_PARAM_STRING("output") + " output parameter.");
// Example.
BINDING_EXAMPLE(
"The following command can be used to generate 100 samples from the pre-"
"trained GMM " + PRINT_MODEL("gmm") + " and store those generated "
"samples in " + PRINT_DATASET("samples") + ":"
"\n\n" +
PRINT_CALL("gmm_generate", "input_model", "gmm", "samples", 100, "output",
"samples"),
SEE_ALSO("@gmm_train", "#gmm_train"),
SEE_ALSO("@gmm_probability", "#gmm_probability"),
SEE_ALSO("Gaussian Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Mixture_model#Gaussian_mixture_model"),
SEE_ALSO("mlpack::gmm::GMM class documentation",
"@doxygen/classmlpack_1_1gmm_1_1GMM.html"));
"samples"));
// See also...
BINDING_SEE_ALSO("@gmm_train", "#gmm_train");
BINDING_SEE_ALSO("@gmm_probability", "#gmm_probability");
BINDING_SEE_ALSO("Gaussian Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Mixture_model#Gaussian_mixture_model");
BINDING_SEE_ALSO("mlpack::gmm::GMM class documentation",
"@doxygen/classmlpack_1_1gmm_1_1GMM.html");
PARAM_MODEL_IN_REQ(GMM, "input_model", "Input GMM model to generate samples "
"from.", "m");
+22 -13
View File
@@ -19,32 +19,41 @@ using namespace mlpack;
using namespace mlpack::gmm;
using namespace mlpack::util;
PROGRAM_INFO("GMM Probability Calculator",
// Short description.
// Program Name.
BINDING_NAME("GMM Probability Calculator");
// Short description.
BINDING_SHORT_DESC(
"A probability calculator for GMMs. Given a pre-trained GMM and a set of "
"points, this can compute the probability that each point is from the given"
" GMM.",
// Long description.
" GMM.");
// Long description.
BINDING_LONG_DESC(
"This program calculates the probability that given points came from a "
"given GMM (that is, P(X | gmm)). The GMM is specified with the " +
PRINT_PARAM_STRING("input_model") + " parameter, and the points are "
"specified with the " + PRINT_PARAM_STRING("input") + " parameter. The "
"output probabilities may be saved via the " +
PRINT_PARAM_STRING("output") + " output parameter."
"\n\n"
PRINT_PARAM_STRING("output") + " output parameter.");
// Example.
BINDING_EXAMPLE(
"So, for example, to calculate the probabilities of each point in " +
PRINT_DATASET("points") + " coming from the pre-trained GMM " +
PRINT_MODEL("gmm") + ", while storing those probabilities in " +
PRINT_DATASET("probs") + ", the following command could be used:"
"\n\n" +
PRINT_CALL("gmm_probability", "input_model", "gmm", "input", "points",
"output", "probs"),
SEE_ALSO("@gmm_train", "#gmm_train"),
SEE_ALSO("@gmm_generate", "#gmm_generate"),
SEE_ALSO("Gaussian Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Mixture_model#Gaussian_mixture_model"),
SEE_ALSO("mlpack::gmm::GMM class documentation",
"@doxygen/classmlpack_1_1gmm_1_1GMM.html"));
"output", "probs"));
// See also...
BINDING_SEE_ALSO("@gmm_train", "#gmm_train");
BINDING_SEE_ALSO("@gmm_generate", "#gmm_generate");
BINDING_SEE_ALSO("Gaussian Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Mixture_model#Gaussian_mixture_model");
BINDING_SEE_ALSO("mlpack::gmm::GMM class documentation",
"@doxygen/classmlpack_1_1gmm_1_1GMM.html");
PARAM_MODEL_IN_REQ(GMM, "input_model", "Input GMM to use as model.", "m");
PARAM_MATRIX_IN_REQ("input", "Input matrix to calculate probabilities of.",
+22 -13
View File
@@ -26,12 +26,17 @@ using namespace mlpack::util;
using namespace mlpack::kmeans;
using namespace std;
PROGRAM_INFO("Gaussian Mixture Model (GMM) Training",
// Short description.
// Program Name.
BINDING_NAME("Gaussian Mixture Model (GMM) Training");
// Short description.
BINDING_SHORT_DESC(
"An implementation of the EM algorithm for training Gaussian mixture "
"models (GMMs). Given a dataset, this can train a GMM for future use "
"with other tools.",
// Long description.
"with other tools.");
// Long description.
BINDING_LONG_DESC(
"This program takes a parametric estimate of a Gaussian mixture model (GMM)"
" using the EM algorithm to find the maximum likelihood estimate. The "
"model may be saved and reused by other mlpack GMM tools."
@@ -77,8 +82,10 @@ PROGRAM_INFO("Gaussian Mixture Model (GMM) Training",
"will avoid the checks after each iteration of the EM algorithm which "
"ensure that the covariance matrices are positive definite. Specifying "
"the flag can cause faster runtime, but may also cause non-positive "
"definite covariance matrices, which will cause the program to crash."
"\n\n"
"definite covariance matrices, which will cause the program to crash.");
// Example.
BINDING_EXAMPLE(
"As an example, to train a 6-Gaussian GMM on the data in " +
PRINT_DATASET("data") + " with a maximum of 100 iterations of EM and 3 "
"trials, saving the trained GMM to " + PRINT_MODEL("gmm") + ", the "
@@ -91,13 +98,15 @@ PROGRAM_INFO("Gaussian Mixture Model (GMM) Training",
", the following command may be used: "
"\n\n" +
PRINT_CALL("gmm_train", "input_model", "gmm", "input", "data2",
"gaussians", 6, "output_model", "new_gmm"),
SEE_ALSO("@gmm_generate", "#gmm_generate"),
SEE_ALSO("@gmm_probability", "#gmm_probability"),
SEE_ALSO("Gaussian Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Mixture_model#Gaussian_mixture_model"),
SEE_ALSO("mlpack::gmm::GMM class documentation",
"@doxygen/classmlpack_1_1gmm_1_1GMM.html"));
"gaussians", 6, "output_model", "new_gmm"));
// See also...
BINDING_SEE_ALSO("@gmm_generate", "#gmm_generate");
BINDING_SEE_ALSO("@gmm_probability", "#gmm_probability");
BINDING_SEE_ALSO("Gaussian Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Mixture_model#Gaussian_mixture_model");
BINDING_SEE_ALSO("mlpack::gmm::GMM class documentation",
"@doxygen/classmlpack_1_1gmm_1_1GMM.html");
// Parameters for training.
PARAM_MATRIX_IN_REQ("input", "The training data on which the model will be "
+23 -14
View File
@@ -30,12 +30,17 @@ using namespace mlpack::math;
using namespace arma;
using namespace std;
PROGRAM_INFO("Hidden Markov Model (HMM) Sequence Generator",
// Short description.
// Program Name.
BINDING_NAME("Hidden Markov Model (HMM) Sequence Generator");
// Short description.
BINDING_SHORT_DESC(
"A utility to generate random sequences from a pre-trained Hidden Markov "
"Model (HMM). The length of the desired sequence can be specified, and a "
"random sequence of observations is returned.",
// Long description.
"random sequence of observations is returned.");
// Long description.
BINDING_LONG_DESC(
"This utility takes an already-trained HMM, specified as the " +
PRINT_PARAM_STRING("model") + " parameter, and generates a random "
"observation sequence and hidden state sequence based on its parameters. "
@@ -45,22 +50,26 @@ PROGRAM_INFO("Hidden Markov Model (HMM) Sequence Generator",
" parameter."
"\n\n"
"The state to start the sequence in may be specified with the " +
PRINT_PARAM_STRING("start_state") + " parameter."
"\n\n"
PRINT_PARAM_STRING("start_state") + " parameter.");
// Example.
BINDING_EXAMPLE(
"For example, to generate a sequence of length 150 from the HMM " +
PRINT_MODEL("hmm") + " and save the observation sequence to " +
PRINT_DATASET("observations") + " and the hidden state sequence to " +
PRINT_DATASET("states") + ", the following command may be used: "
"\n\n" +
PRINT_CALL("hmm_generate", "model", "hmm", "length", 150, "output",
"observations", "state", "states"),
SEE_ALSO("@hmm_train", "#hmm_train"),
SEE_ALSO("@hmm_loglik", "#hmm_loglik"),
SEE_ALSO("@hmm_viterbi", "#hmm_viterbi"),
SEE_ALSO("Hidden Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Hidden_Markov_model"),
SEE_ALSO("mlpack::hmm::HMM class documentation",
"@doxygen/classmlpack_1_1hmm_1_1HMM.html"));
"observations", "state", "states"));
// See also...
BINDING_SEE_ALSO("@hmm_train", "#hmm_train");
BINDING_SEE_ALSO("@hmm_loglik", "#hmm_loglik");
BINDING_SEE_ALSO("@hmm_viterbi", "#hmm_viterbi");
BINDING_SEE_ALSO("Hidden Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Hidden_Markov_model");
BINDING_SEE_ALSO("mlpack::hmm::HMM class documentation",
"@doxygen/classmlpack_1_1hmm_1_1HMM.html");
PARAM_MODEL_IN_REQ(HMMModel, "model", "Trained HMM to generate sequences with.",
"m");
+23 -14
View File
@@ -27,31 +27,40 @@ using namespace mlpack::gmm;
using namespace arma;
using namespace std;
PROGRAM_INFO("Hidden Markov Model (HMM) Sequence Log-Likelihood",
// Short description.
// Program Name.
BINDING_NAME("Hidden Markov Model (HMM) Sequence Log-Likelihood");
// Short description.
BINDING_SHORT_DESC(
"A utility for computing the log-likelihood of a sequence for Hidden Markov"
" Models (HMMs). Given a pre-trained HMM and an observation sequence, this"
" computes and returns the log-likelihood of that sequence being observed "
"from that HMM.",
// Long description.
"from that HMM.");
// Long description.
BINDING_LONG_DESC(
"This utility takes an already-trained HMM, specified with the " +
PRINT_PARAM_STRING("input_model") + " parameter, and evaluates the "
"log-likelihood of a sequence of observations, given with the " +
PRINT_PARAM_STRING("input") + " parameter. The computed log-likelihood is"
" given as output."
"\n\n"
" given as output.");
// Example.
BINDING_EXAMPLE(
"For example, to compute the log-likelihood of the sequence " +
PRINT_DATASET("seq") + " with the pre-trained HMM " + PRINT_MODEL("hmm") +
", the following command may be used: "
"\n\n" +
PRINT_CALL("hmm_loglik", "input", "seq", "input_model", "hmm"),
SEE_ALSO("@hmm_train", "#hmm_train"),
SEE_ALSO("@hmm_generate", "#hmm_generate"),
SEE_ALSO("@hmm_viterbi", "#hmm_viterbi"),
SEE_ALSO("Hidden Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Hidden_Markov_model"),
SEE_ALSO("mlpack::hmm::HMM class documentation",
"@doxygen/classmlpack_1_1hmm_1_1HMM.html"));
PRINT_CALL("hmm_loglik", "input", "seq", "input_model", "hmm"));
// See also...
BINDING_SEE_ALSO("@hmm_train", "#hmm_train");
BINDING_SEE_ALSO("@hmm_generate", "#hmm_generate");
BINDING_SEE_ALSO("@hmm_viterbi", "#hmm_viterbi");
BINDING_SEE_ALSO("Hidden Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Hidden_Markov_model");
BINDING_SEE_ALSO("mlpack::hmm::HMM class documentation",
"@doxygen/classmlpack_1_1hmm_1_1HMM.html");
PARAM_MATRIX_IN_REQ("input", "File containing observations,", "i");
PARAM_MODEL_IN_REQ(HMMModel, "input_model", "File containing HMM.", "m");
+19 -12
View File
@@ -28,12 +28,17 @@ using namespace mlpack::math;
using namespace arma;
using namespace std;
PROGRAM_INFO("Hidden Markov Model (HMM) Training",
// Short description.
// Program Name.
BINDING_NAME("Hidden Markov Model (HMM) Training");
// Short description.
BINDING_SHORT_DESC(
"An implementation of training algorithms for Hidden Markov Models (HMMs). "
"Given labeled or unlabeled data, an HMM can be trained for further use "
"with other mlpack HMM tools.",
// Long description.
"with other mlpack HMM tools.");
// Long description.
BINDING_LONG_DESC(
"This program allows a Hidden Markov Model to be trained on labeled or "
"unlabeled data. It supports four types of HMMs: Discrete HMMs, "
"Gaussian HMMs, GMM HMMs, or Diagonal GMM HMMs"
@@ -53,14 +58,16 @@ PROGRAM_INFO("Hidden Markov Model (HMM) Training",
"\n\n"
"Optionally, a pre-created HMM model can be used as a guess for the "
"transition matrix and emission probabilities; this is specifiable with "
"--model_file.",
SEE_ALSO("@hmm_generate", "#hmm_generate"),
SEE_ALSO("@hmm_loglik", "#hmm_loglik"),
SEE_ALSO("@hmm_viterbi", "#hmm_viterbi"),
SEE_ALSO("Hidden Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Hidden_Markov_model"),
SEE_ALSO("mlpack::hmm::HMM class documentation",
"@doxygen/classmlpack_1_1hmm_1_1HMM.html"));
"--model_file.");
// See also...
BINDING_SEE_ALSO("@hmm_generate", "#hmm_generate");
BINDING_SEE_ALSO("@hmm_loglik", "#hmm_loglik");
BINDING_SEE_ALSO("@hmm_viterbi", "#hmm_viterbi");
BINDING_SEE_ALSO("Hidden Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Hidden_Markov_model");
BINDING_SEE_ALSO("mlpack::hmm::HMM class documentation",
"@doxygen/classmlpack_1_1hmm_1_1HMM.html");
PARAM_STRING_IN_REQ("input_file", "File containing input observations.", "i");
PARAM_STRING_IN("type", "Type of HMM: discrete | gaussian | diag_gmm | gmm.",
+23 -14
View File
@@ -28,34 +28,43 @@ using namespace mlpack::gmm;
using namespace arma;
using namespace std;
PROGRAM_INFO("Hidden Markov Model (HMM) Viterbi State Prediction",
// Short description.
// Program Name.
BINDING_NAME("Hidden Markov Model (HMM) Viterbi State Prediction");
// Short description.
BINDING_SHORT_DESC(
"A utility for computing the most probable hidden state sequence for Hidden"
" Markov Models (HMMs). Given a pre-trained HMM and an observed sequence, "
"this uses the Viterbi algorithm to compute and return the most probable "
"hidden state sequence.",
// Long description.
"hidden state sequence.");
// Long description.
BINDING_LONG_DESC(
"This utility takes an already-trained HMM, specified as " +
PRINT_PARAM_STRING("input_model") + ", and evaluates the most probable "
"hidden state sequence of a given sequence of observations (specified as "
"'" + PRINT_PARAM_STRING("input") + ", using the Viterbi algorithm. The "
"computed state sequence may be saved using the " +
PRINT_PARAM_STRING("output") + " output parameter."
"\n\n"
PRINT_PARAM_STRING("output") + " output parameter.");
// Example.
BINDING_EXAMPLE(
"For example, to predict the state sequence of the observations " +
PRINT_DATASET("obs") + " using the HMM " + PRINT_MODEL("hmm") + ", "
"storing the predicted state sequence to " + PRINT_DATASET("states") +
", the following command could be used:"
"\n\n" +
PRINT_CALL("hmm_viterbi", "input", "obs", "input_model", "hmm", "output",
"states"),
SEE_ALSO("@hmm_train", "#hmm_train"),
SEE_ALSO("@hmm_generate", "#hmm_generate"),
SEE_ALSO("@hmm_loglik", "#hmm_loglik"),
SEE_ALSO("Hidden Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Hidden_Markov_model"),
SEE_ALSO("mlpack::hmm::HMM class documentation",
"@doxygen/classmlpack_1_1hmm_1_1HMM.html"));
"states"));
// See also...
BINDING_SEE_ALSO("@hmm_train", "#hmm_train");
BINDING_SEE_ALSO("@hmm_generate", "#hmm_generate");
BINDING_SEE_ALSO("@hmm_loglik", "#hmm_loglik");
BINDING_SEE_ALSO("Hidden Mixture Models on Wikipedia",
"https://en.wikipedia.org/wiki/Hidden_Markov_model");
BINDING_SEE_ALSO("mlpack::hmm::HMM class documentation",
"@doxygen/classmlpack_1_1hmm_1_1HMM.html");
PARAM_MATRIX_IN_REQ("input", "Matrix containing observations,", "i");
PARAM_MODEL_IN_REQ(HMMModel, "input_model", "Trained HMM to use.", "m");
@@ -25,13 +25,18 @@ using namespace mlpack::tree;
using namespace mlpack::data;
using namespace mlpack::util;
PROGRAM_INFO("Hoeffding trees",
// Short description.
// Program Name.
BINDING_NAME("Hoeffding trees");
// Short description.
BINDING_SHORT_DESC(
"An implementation of Hoeffding trees, a form of streaming decision tree "
"for classification. Given labeled data, a Hoeffding tree can be trained "
"and saved for later use, or a pre-trained Hoeffding tree can be used for "
"predicting the classifications of new points.",
// Long description.
"predicting the classifications of new points.");
// Long description.
BINDING_LONG_DESC(
"This program implements Hoeffding trees, a form of streaming decision tree"
" suited best for large (or streaming) datasets. This program supports "
"both categorical and numeric data. Given an input dataset, this program "
@@ -61,8 +66,10 @@ PROGRAM_INFO("Hoeffding trees",
" parameter. Predictions for each test point may be saved with the " +
PRINT_PARAM_STRING("predictions") + " output parameter, and class "
"probabilities for each prediction may be saved with the " +
PRINT_PARAM_STRING("probabilities") + " output parameter."
"\n\n"
PRINT_PARAM_STRING("probabilities") + " output parameter.");
// Example.
BINDING_EXAMPLE(
"For example, to train a Hoeffding tree with confidence 0.99 with data " +
PRINT_DATASET("dataset") + ", saving the trained tree to " +
PRINT_MODEL("tree") + ", the following command may be used:"
@@ -76,13 +83,15 @@ PROGRAM_INFO("Hoeffding trees",
PRINT_DATASET("class_probs") + " with the following command: "
"\n\n" +
PRINT_CALL("hoeffding_tree", "input_model", "tree", "test", "test_set",
"predictions", "predictions", "probabilities", "class_probs"),
SEE_ALSO("@decision_tree", "#decision_tree"),
SEE_ALSO("@random_forest", "#random_forest"),
SEE_ALSO("Mining High-Speed Data Streams (pdf)",
"http://dm.cs.washington.edu/papers/vfdt-kdd00.pdf"),
SEE_ALSO("mlpack::tree::HoeffdingTree class documentation",
"@doxygen/classmlpack_1_1tree_1_1HoeffdingTree.html"));
"predictions", "predictions", "probabilities", "class_probs"));
// See also...
BINDING_SEE_ALSO("@decision_tree", "#decision_tree");
BINDING_SEE_ALSO("@random_forest", "#random_forest");
BINDING_SEE_ALSO("Mining High-Speed Data Streams (pdf)",
"http://dm.cs.washington.edu/papers/vfdt-kdd00.pdf");
BINDING_SEE_ALSO("mlpack::tree::HoeffdingTree class documentation",
"@doxygen/classmlpack_1_1tree_1_1HoeffdingTree.html");
PARAM_MATRIX_AND_INFO_IN("training", "Training dataset (may be categorical).",
"t");
+26 -19
View File
@@ -22,14 +22,18 @@ using namespace mlpack::kde;
using namespace mlpack::util;
using namespace std;
// Define parameters for the executable.
PROGRAM_INFO("Kernel Density Estimation",
// Short description.
// Program Name.
BINDING_NAME("Kernel Density Estimation");
// Short description.
BINDING_SHORT_DESC(
"An implementation of kernel density estimation with dual-tree algorithms. "
"Given a set of reference points and query points and a kernel function, "
"this can estimate the density function at the location of each query point"
" using trees; trees that are built can be saved for later use.",
// Long description.
" using trees; trees that are built can be saved for later use.");
// Long description.
BINDING_LONG_DESC(
"This program performs a Kernel Density Estimation. KDE is a "
"non-parametric way of estimating probability density function. "
"For each query point the program will estimate its probability density "
@@ -68,8 +72,10 @@ PROGRAM_INFO("Kernel Density Estimation",
"computations an exact approach would take, this program recurses the tree "
"whenever a fraction of the amount of the node's descendant points have "
"already been computed. This fraction is set using " +
PRINT_PARAM_STRING("mc_break_coef") + "."
"\n\n"
PRINT_PARAM_STRING("mc_break_coef") + ".");
// Example.
BINDING_EXAMPLE(
"For example, the following will run KDE using the data in " +
PRINT_DATASET("ref_data") + " for training and the data in " +
PRINT_DATASET("qu_data") + " as query data. It will apply an Epanechnikov "
@@ -108,19 +114,20 @@ PROGRAM_INFO("Kernel Density Estimation",
0.2, "kernel", "gaussian", "tree", "kd-tree", "rel_error",
0.05, "predictions", "out_data", "monte_carlo", "", "mc_probability",
0.95, "initial_sample_size", 200, "mc_entry_coef", 3.5, "mc_break_coef",
0.6) +
"\n\n",
SEE_ALSO("@knn", "#knn"),
SEE_ALSO("Kernel density estimation on Wikipedia",
"https://en.wikipedia.org/wiki/Kernel_density_estimation"),
SEE_ALSO("Tree-Independent Dual-Tree Algorithms",
"https://arxiv.org/pdf/1304.4327.pdf"),
SEE_ALSO("Fast High-dimensional Kernel Summations Using the Monte Carlo "
"Multipole Method", "http://papers.nips.cc/paper/3539-fast-high-"
0.6));
// See also...
BINDING_SEE_ALSO("@knn", "#knn");
BINDING_SEE_ALSO("Kernel density estimation on Wikipedia",
"https://en.wikipedia.org/wiki/Kernel_density_estimation");
BINDING_SEE_ALSO("Tree-Independent Dual-Tree Algorithms",
"https://arxiv.org/pdf/1304.4327.pdf");
BINDING_SEE_ALSO("Fast High-dimensional Kernel Summations Using the Monte Carlo"
" Multipole Method", "http://papers.nips.cc/paper/3539-fast-high-"
"dimensional-kernel-summations-using-the-monte-carlo-multipole-method."
"pdf"),
SEE_ALSO("mlpack::kde::KDE C++ class documentation",
"@doxygen/classmlpack_1_1kde_1_1KDE.html"));
"pdf");
BINDING_SEE_ALSO("mlpack::kde::KDE C++ class documentation",
"@doxygen/classmlpack_1_1kde_1_1KDE.html");
// Required options.
PARAM_MATRIX_IN("reference", "Input reference dataset use for KDE.", "r");
@@ -40,12 +40,17 @@ using namespace mlpack::util;
using namespace std;
using namespace arma;
PROGRAM_INFO("Kernel Principal Components Analysis",
// Short description.
// Program Name.
BINDING_NAME("Kernel Principal Components Analysis");
// Short description.
BINDING_SHORT_DESC(
"An implementation of Kernel Principal Components Analysis (KPCA). This "
"can be used to perform nonlinear dimensionality reduction or preprocessing"
" on a given dataset.",
// Long description.
" on a given dataset.");
// Long description.
BINDING_LONG_DESC(
"This program performs Kernel Principal Components Analysis (KPCA) on the "
"specified dataset with the specified kernel. This will transform the "
"data onto the kernel principal components, and optionally reduce the "
@@ -55,13 +60,6 @@ PROGRAM_INFO("Kernel Principal Components Analysis",
"For the case where a linear kernel is used, this reduces to regular "
"PCA."
"\n\n"
"For example, the following command will perform KPCA on the dataset " +
PRINT_DATASET("input") + " using the Gaussian kernel, and saving the "
"transformed data to " + PRINT_DATASET("transformed") + ": "
"\n\n" +
PRINT_CALL("kernel_pca", "input", "input", "kernel", "gaussian", "output",
"transformed") +
"\n\n"
"The kernels that are supported are listed below:"
"\n\n"
" * 'linear': the standard linear dot product (same as normal PCA):\n"
@@ -98,13 +96,24 @@ PROGRAM_INFO("Kernel Principal Components Analysis",
"the kernel matrix; to specify the sampling scheme, the " +
PRINT_PARAM_STRING("sampling") + " parameter is used. The "
"sampling scheme for the Nystroem method can be chosen from the "
"following list: 'kmeans', 'random', 'ordered'.",
SEE_ALSO("Kernel principal component analysis on Wikipedia",
"https://en.wikipedia.org/wiki/Kernel_principal_component_analysis"),
SEE_ALSO("Kernel Principal Component Analysis (pdf)",
"http://pca.narod.ru/scholkopf_kernel.pdf"),
SEE_ALSO("mlpack::kpca::KernelPCA class documentation",
"@doxygen/classmlpack_1_1kpca_1_1KernelPCA.html"));
"following list: 'kmeans', 'random', 'ordered'.");
// Example.
BINDING_EXAMPLE(
"For example, the following command will perform KPCA on the dataset " +
PRINT_DATASET("input") + " using the Gaussian kernel, and saving the "
"transformed data to " + PRINT_DATASET("transformed") + ": "
"\n\n" +
PRINT_CALL("kernel_pca", "input", "input", "kernel", "gaussian", "output",
"transformed"));
// See also...
BINDING_SEE_ALSO("Kernel principal component analysis on Wikipedia",
"https://en.wikipedia.org/wiki/Kernel_principal_component_analysis");
BINDING_SEE_ALSO("Kernel Principal Component Analysis (pdf)",
"http://pca.narod.ru/scholkopf_kernel.pdf");
BINDING_SEE_ALSO("mlpack::kpca::KernelPCA class documentation",
"@doxygen/classmlpack_1_1kpca_1_1KernelPCA.html");
PARAM_MATRIX_IN_REQ("input", "Input dataset to perform KPCA on.", "i");
PARAM_MATRIX_OUT("output", "Matrix to save modified dataset to.", "o");
+29 -21
View File
@@ -27,13 +27,17 @@ using namespace mlpack::kmeans;
using namespace mlpack::util;
using namespace std;
// Define parameters for the executable.
PROGRAM_INFO("K-Means Clustering",
// Short description.
// Program Name.
BINDING_NAME("K-Means Clustering");
// Short description.
BINDING_SHORT_DESC(
"An implementation of several strategies for efficient k-means clustering. "
"Given a dataset and a value of k, this computes and returns a k-means "
"clustering on that data.",
// Long description.
"clustering on that data.");
// Long description.
BINDING_LONG_DESC(
"This program performs K-Means clustering on the given dataset. It can "
"return the learned cluster assignments, and the centroids of the clusters."
" Empty clusters are not allowed by default; when a cluster becomes empty,"
@@ -74,8 +78,10 @@ PROGRAM_INFO("K-Means Clustering",
"Initial clustering assignments may be specified using the " +
PRINT_PARAM_STRING("initial_centroids") + " parameter, and the maximum "
"number of iterations may be specified with the " +
PRINT_PARAM_STRING("max_iterations") + " parameter."
"\n\n"
PRINT_PARAM_STRING("max_iterations") + " parameter.");
// Example.
BINDING_EXAMPLE(
"As an example, to use Hamerly's algorithm to perform k-means clustering "
"with k=10 on the dataset " + PRINT_DATASET("data") + ", saving the "
"centroids to " + PRINT_DATASET("centroids") + " and the assignments for "
@@ -91,21 +97,23 @@ PROGRAM_INFO("K-Means Clustering",
"following command may be used:"
"\n\n" +
PRINT_CALL("kmeans", "input", "data", "initial_centroids", "initial",
"clusters", 10, "max_iterations", 500, "centroid", "final"),
SEE_ALSO("K-Means tutorial", "@doxygen/kmtutorial.html"),
SEE_ALSO("@dbscan", "#dbscan"),
SEE_ALSO("Using the triangle inequality to accelerate k-means (pdf)",
"http://www.aaai.org/Papers/ICML/2003/ICML03-022.pdf"),
SEE_ALSO("Making k-means even faster (pdf)",
"clusters", 10, "max_iterations", 500, "centroid", "final"));
// See also...
BINDING_SEE_ALSO("K-Means tutorial", "@doxygen/kmtutorial.html");
BINDING_SEE_ALSO("@dbscan", "#dbscan");
BINDING_SEE_ALSO("Using the triangle inequality to accelerate k-means (pdf)",
"http://www.aaai.org/Papers/ICML/2003/ICML03-022.pdf");
BINDING_SEE_ALSO("Making k-means even faster (pdf)",
"http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.586.2554"
"&rep=rep1&type=pdf"),
SEE_ALSO("Accelerating exact k-means algorithms with geometric reasoning "
"(pdf)", "http://reports-archive.adm.cs.cmu.edu/anon/anon/usr/ftp/"
"usr0/ftp/2000/CMU-CS-00-105.pdf"),
SEE_ALSO("A dual-tree algorithm for fast k-means clustering with large k "
"(pdf)", "http://www.ratml.org/pub/pdf/2017dual.pdf"),
SEE_ALSO("mlpack::kmeans::KMeans class documentation",
"@doxygen/classmlpack_1_1kmeans_1_1KMeans.html"));
"&rep=rep1&type=pdf");
BINDING_SEE_ALSO("Accelerating exact k-means algorithms with geometric"
" reasoning (pdf)", "http://reports-archive.adm.cs.cmu.edu/anon/anon"
"/usr/ftp/usr0/ftp/2000/CMU-CS-00-105.pdf");
BINDING_SEE_ALSO("A dual-tree algorithm for fast k-means clustering with large "
"k (pdf)", "http://www.ratml.org/pub/pdf/2017dual.pdf");
BINDING_SEE_ALSO("mlpack::kmeans::KMeans class documentation",
"@doxygen/classmlpack_1_1kmeans_1_1KMeans.html");
// Required options.
PARAM_MATRIX_IN_REQ("input", "Input dataset to perform clustering on.", "i");
+21 -12
View File
@@ -21,13 +21,18 @@ using namespace mlpack;
using namespace mlpack::regression;
using namespace mlpack::util;
PROGRAM_INFO("LARS",
// Short description.
// Program Name.
BINDING_NAME("LARS");
// Short description.
BINDING_SHORT_DESC(
"An implementation of Least Angle Regression (Stagewise/laSso), also known"
" as LARS. This can train a LARS/LASSO/Elastic Net model and use that "
"model or a pre-trained model to output regression predictions for a test "
"set.",
// Long description.
"set.");
// Long description.
BINDING_LONG_DESC(
"An implementation of LARS: Least Angle Regression (Stagewise/laSso). "
"This is a stage-wise homotopy-based algorithm for L1-regularized linear "
"regression (LASSO) and L1+L2-regularized linear regression (Elastic Net)."
@@ -70,8 +75,10 @@ PROGRAM_INFO("LARS",
"trained model or the given input model. Test points can be specified with"
" the " + PRINT_PARAM_STRING("test") + " parameter. Predicted responses "
"to the test points can be saved with the " +
PRINT_PARAM_STRING("output_predictions") + " output parameter."
"\n\n"
PRINT_PARAM_STRING("output_predictions") + " output parameter.");
// Example.
BINDING_EXAMPLE(
"For example, the following command trains a model on the data " +
PRINT_DATASET("data") + " and responses " + PRINT_DATASET("responses") +
" with lambda1 set to 0.4 and lambda2 set to 0 (so, LASSO is being "
@@ -86,12 +93,14 @@ PROGRAM_INFO("LARS",
"and save those responses to " + PRINT_DATASET("test_predictions") + ": "
"\n\n" +
PRINT_CALL("lars", "input_model", "lasso_model", "test", "test",
"output_predictions", "test_predictions"),
SEE_ALSO("@linear_regression", "#linear_regression"),
SEE_ALSO("Least angle regression (pdf)",
"http://mlpack.org/papers/lars.pdf"),
SEE_ALSO("mlpack::regression::LARS C++ class documentation",
"@doxygen/classmlpack_1_1regression_1_1LARS.html"));
"output_predictions", "test_predictions"));
// See also...
BINDING_SEE_ALSO("@linear_regression", "#linear_regression");
BINDING_SEE_ALSO("Least angle regression (pdf)",
"http://mlpack.org/papers/lars.pdf");
BINDING_SEE_ALSO("mlpack::regression::LARS C++ class documentation",
"@doxygen/classmlpack_1_1regression_1_1LARS.html");
PARAM_TMATRIX_IN("input", "Matrix of covariates (X).", "i");
PARAM_MATRIX_IN("responses", "Matrix of responses/observations (y).", "r");
@@ -21,13 +21,18 @@ using namespace mlpack::util;
using namespace arma;
using namespace std;
PROGRAM_INFO("Simple Linear Regression and Prediction",
// Short description.
// Program Name.
BINDING_NAME("Simple Linear Regression and Prediction");
// Short description.
BINDING_SHORT_DESC(
"An implementation of simple linear regression and ridge regression using "
"ordinary least squares. Given a dataset and responses, a model can be "
"trained and saved for later use, or a pre-trained model can be used to "
"output regression predictions for a test set.",
// Long description.
"output regression predictions for a test set.");
// Long description.
BINDING_LONG_DESC(
"An implementation of simple linear regression and simple ridge regression "
"using ordinary least squares. This solves the problem"
"\n\n"
@@ -53,8 +58,10 @@ PROGRAM_INFO("Simple Linear Regression and Prediction",
"and the predicted responses y' may be saved with the " +
PRINT_PARAM_STRING("output_predictions") + " output parameter. This type "
"of regression is related to least-angle regression, which mlpack "
"implements as the 'lars' program."
"\n\n"
"implements as the 'lars' program.");
// Example.
BINDING_EXAMPLE(
"For example, to run a linear regression on the dataset " +
PRINT_DATASET("X") + " with responses " + PRINT_DATASET("y") + ", saving "
"the trained model to " + PRINT_MODEL("lr_model") + ", the following "
@@ -69,13 +76,17 @@ PROGRAM_INFO("Simple Linear Regression and Prediction",
"used:"
"\n\n" +
PRINT_CALL("linear_regression", "input_model", "lr_model", "test", "X_test",
"output_predictions", "X_test_responses"),
SEE_ALSO("Linear/ridge regression tutorial", "@doxygen/lrtutorial.html"),
SEE_ALSO("@lars", "#lars"),
SEE_ALSO("Linear regression on Wikipedia",
"https://en.wikipedia.org/wiki/Linear_regression"),
SEE_ALSO("mlpack::regression::LinearRegression C++ class documentation",
"@doxygen/classmlpack_1_1regression_1_1LinearRegression.html"));
"output_predictions", "X_test_responses"));
// See also...
BINDING_SEE_ALSO("Linear/ridge regression tutorial",
"@doxygen/lrtutorial.html");
BINDING_SEE_ALSO("@lars", "#lars");
BINDING_SEE_ALSO("Linear regression on Wikipedia",
"https://en.wikipedia.org/wiki/Linear_regression");
BINDING_SEE_ALSO("mlpack::regression::LinearRegression C++ class "
"documentation",
"@doxygen/classmlpack_1_1regression_1_1LinearRegression.html");
PARAM_MATRIX_IN("training", "Matrix containing training set X (regressors).",
"t");
@@ -23,12 +23,17 @@ using namespace mlpack;
using namespace mlpack::svm;
using namespace mlpack::util;
PROGRAM_INFO("Linear SVM is an L2-regularized support vector machine.",
// Short description.
// Program Name.
BINDING_NAME("Linear SVM is an L2-regularized support vector machine.");
// Short description.
BINDING_SHORT_DESC(
"An implementation of linear SVM for multiclass classification. "
"Given labeled data, a model can be trained and saved for "
"future use; or, a pre-trained model can be used to classify new points.",
// Long description.
"future use; or, a pre-trained model can be used to classify new points.");
// Long description.
BINDING_LONG_DESC(
"An implementation of linear SVMs that uses either L-BFGS or parallel SGD"
" (stochastic gradient descent) to train the model."
"\n\n"
@@ -77,8 +82,10 @@ PROGRAM_INFO("Linear SVM is an L2-regularized support vector machine.",
"so long as an existing linear SVM model is given with the " +
PRINT_PARAM_STRING("input_model") + " parameter. The output predictions "
"from the linear SVM model may be saved with the " +
PRINT_PARAM_STRING("predictions") + " parameter." +
"\n\n"
PRINT_PARAM_STRING("predictions") + " parameter.");
// Example.
BINDING_EXAMPLE(
"As an example, to train a LinaerSVM on the data '" +
PRINT_DATASET("data") + "' with labels '" + PRINT_DATASET("labels") + "' "
"with L2 regularization of 0.1, saving the model to '" +
@@ -93,13 +100,15 @@ PROGRAM_INFO("Linear SVM is an L2-regularized support vector machine.",
PRINT_DATASET("predictions") + "', the following command may be used: "
"\n\n" +
PRINT_CALL("linear_svm", "input_model", "lsvm_model", "test", "test",
"predictions", "predictions"),
SEE_ALSO("@random_forest", "#random_forest"),
SEE_ALSO("@logistic_regression", "#logistic_regression"),
SEE_ALSO("LinearSVM on Wikipedia",
"https://en.wikipedia.org/wiki/Support-vector_machine"),
SEE_ALSO("mlpack::svm::LinearSVM C++ class documentation",
"@doxygen/classmlpack_1_1svm_1_1LinearSVM.html"));
"predictions", "predictions"));
// See also...
BINDING_SEE_ALSO("@random_forest", "#random_forest");
BINDING_SEE_ALSO("@logistic_regression", "#logistic_regression");
BINDING_SEE_ALSO("LinearSVM on Wikipedia",
"https://en.wikipedia.org/wiki/Support-vector_machine");
BINDING_SEE_ALSO("mlpack::svm::LinearSVM C++ class documentation",
"@doxygen/classmlpack_1_1svm_1_1LinearSVM.html");
// Training parameters.
PARAM_MATRIX_IN("training", "A matrix containing the training set (the matrix "
+23 -15
View File
@@ -21,14 +21,18 @@
#include <ensmallen.hpp>
// Define parameters.
PROGRAM_INFO("Large Margin Nearest Neighbors (LMNN)",
// Short description.
// Program Name.
BINDING_NAME("Large Margin Nearest Neighbors (LMNN)");
// Short description.
BINDING_SHORT_DESC(
"An implementation of Large Margin Nearest Neighbors (LMNN), a distance "
"learning technique. Given a labeled dataset, this learns a transformation"
" of the data that improves k-nearest-neighbor performance; this can be "
"useful as a preprocessing step.",
// Long description.
"useful as a preprocessing step.");
// Long description.
BINDING_LONG_DESC(
"This program implements Large Margin Nearest Neighbors, a distance "
"learning technique. The method seeks to improve k-nearest-neighbor "
"classification on a dataset. The method employes the strategy of "
@@ -111,8 +115,10 @@ PROGRAM_INFO("Large Margin Nearest Neighbors (LMNN)",
"literature on L-BFGS. In addition, a normalized starting point can be "
"used by specifying the " + PRINT_PARAM_STRING("normalize") + " parameter."
"\n\n"
"By default, the AMSGrad optimizer is used."
"\n\n"
"By default, the AMSGrad optimizer is used.");
// Example.
BINDING_EXAMPLE(
"Example - Let's say we want to learn distance on iris dataset with "
"number of targets as 3 using BigBatch_SGD optimizer. A simple call for "
"the same will look like: "
@@ -124,15 +130,17 @@ PROGRAM_INFO("Large Margin Nearest Neighbors (LMNN)",
"with dataset having labels as last column can be made as: "
"\n\n" +
PRINT_CALL("mlpack_lmnn", "input", "letter_recognition", "k", 5,
"range", 10, "regularization", 0.4, "output", "output"),
SEE_ALSO("@nca", "#nca"),
SEE_ALSO("Large margin nearest neighbor on Wikipedia",
"https://en.wikipedia.org/wiki/Large_margin_nearest_neighbor"),
SEE_ALSO("Distance metric learning for large margin nearest neighbor "
"range", 10, "regularization", 0.4, "output", "output"));
// See also...
BINDING_SEE_ALSO("@nca", "#nca");
BINDING_SEE_ALSO("Large margin nearest neighbor on Wikipedia",
"https://en.wikipedia.org/wiki/Large_margin_nearest_neighbor");
BINDING_SEE_ALSO("Distance metric learning for large margin nearest neighbor "
"classification (pdf)", "http://papers.nips.cc/paper/2795-distance-"
"metric-learning-for-large-margin-nearest-neighbor-classification.pdf"),
SEE_ALSO("mlpack::lmnn::LMNN C++ class documentation",
"@doxygen/classmlpack_1_1lmnn_1_1LMNN.html"));
"metric-learning-for-large-margin-nearest-neighbor-classification.pdf");
BINDING_SEE_ALSO("mlpack::lmnn::LMNN C++ class documentation",
"@doxygen/classmlpack_1_1lmnn_1_1LMNN.html");
PARAM_MATRIX_IN_REQ("input", "Input dataset to run LMNN on.", "i");
PARAM_MATRIX_IN("distance", "Initial distance matrix to be used as "
@@ -23,13 +23,18 @@ using namespace mlpack::lcc;
using namespace mlpack::sparse_coding; // For NothingInitializer.
using namespace mlpack::util;
PROGRAM_INFO("Local Coordinate Coding",
// Short description.
// Program Name.
BINDING_NAME("Local Coordinate Coding");
// Short description.
BINDING_SHORT_DESC(
"An implementation of Local Coordinate Coding (LCC), a data transformation "
"technique. Given input data, this transforms each point to be expressed "
"as a linear combination of a few points in the dataset; once an LCC model "
"is trained, it can be used to transform points later also.",
// Long description.
"is trained, it can be used to transform points later also.");
// Long description.
BINDING_LONG_DESC(
"An implementation of Local Coordinate Coding (LCC), which "
"codes data that approximately lives on a manifold using a variation of l1-"
"norm regularized sparse coding. Given a dense data matrix X with n points"
@@ -44,8 +49,10 @@ PROGRAM_INFO("Local Coordinate Coding",
"\n\n"
"The coding is found with an algorithm which alternates between a "
"dictionary step, which updates the dictionary D, and a coding step, which "
"updates the coding matrix Z."
"\n\n"
"updates the coding matrix Z.");
// Example.
BINDING_EXAMPLE(
"To run this program, the input matrix X must be specified (with -i), along"
" with the number of atoms in the dictionary (-k). An initial dictionary "
"may also be specified with the " +
@@ -73,13 +80,15 @@ PROGRAM_INFO("Local Coordinate Coding",
"be used:"
"\n\n" +
PRINT_CALL("local_coordinate_coding", "input_model", "lcc_model", "test",
"points", "codes", "new_codes"),
SEE_ALSO("@sparse_coding", "#sparse_coding"),
SEE_ALSO("Nonlinear learning using local coordinate coding (pdf)",
"points", "codes", "new_codes"));
// See also...
BINDING_SEE_ALSO("@sparse_coding", "#sparse_coding");
BINDING_SEE_ALSO("Nonlinear learning using local coordinate coding (pdf)",
"https://papers.nips.cc/paper/3875-nonlinear-learning-using-local-"
"coordinate-coding.pdf"),
SEE_ALSO("mlpack::lcc::LocalCoordinateCoding C++ class documentation",
"@doxygen/classmlpack_1_1lcc_1_1LocalCoordinateCoding.html"));
"coordinate-coding.pdf");
BINDING_SEE_ALSO("mlpack::lcc::LocalCoordinateCoding C++ class documentation",
"@doxygen/classmlpack_1_1lcc_1_1LocalCoordinateCoding.html");
// Training parameters.
PARAM_MATRIX_IN("training", "Matrix of training data (X).", "t");
@@ -140,12 +140,9 @@ class LogisticRegression
* Using this overload allows configuring the instantiated optimizer before
* training is performed.
*
* Note that the initial point of the optimizer
* (optimizer.Function().GetInitialPoint()) will be used as the initial point
* of the optimization, overwriting any existing trained model. If you don't
* want to overwrite the existing model, set
* optimizer.Function().GetInitialPoint() to the current parameters vector,
* accessible via Parameters().
* This will use the existing model parameters as a starting point for the
* optimization. If this is not what you want, then you should access the
* parameters vector directly with Parameters() and modify it as desired.
*
* @tparam OptimizerType Type of optimizer to use to train the model.
* @tparam CallbackTypes Types of Callback Functions.
@@ -41,24 +41,6 @@ class LogisticRegressionFunction
const arma::Row<size_t>& responses,
const double lambda = 0);
/**
* Creates the LogisticRegressionFunction with initialPoint.
*
* @param predictors The matrix of data points.
* @param responses The measured data for each point in predictors.
* @param initialPoint Point from which to start the optimization.
* @param lambda Regularization constant for ridge regression.
*/
LogisticRegressionFunction(const MatType& predictors,
const arma::Row<size_t>& responses,
const arma::vec& initialPoint,
const double lambda = 0);
//! Return the initial point for the optimization.
const arma::mat& InitialPoint() const { return initialPoint; }
//! Modify the initial point for the optimization.
arma::mat& InitialPoint() { return initialPoint; }
//! Return the regularization parameter (lambda).
const double& Lambda() const { return lambda; }
//! Modify the regularization parameter (lambda).
@@ -170,9 +152,6 @@ class LogisticRegressionFunction
GradType& gradient,
const size_t batchSize = 1) const;
//! Return the initial point for the optimization.
const arma::mat& GetInitialPoint() const { return initialPoint; }
//! Return the number of separable functions (the number of predictor points).
size_t NumFunctions() const { return predictors.n_cols; }
@@ -180,8 +159,6 @@ class LogisticRegressionFunction
size_t NumFeatures() const { return predictors.n_rows + 1; }
private:
//! The initial point, from which to start the optimization.
arma::mat initialPoint;
//! The matrix of data points (predictors). This is an alias until shuffling
//! is done.
MatType predictors;
@@ -31,8 +31,6 @@ LogisticRegressionFunction<MatType>::LogisticRegressionFunction(
false)),
lambda(lambda)
{
initialPoint = arma::rowvec(predictors.n_rows + 1, arma::fill::zeros);
// Sanity check.
if (responses.n_elem != predictors.n_cols)
{
@@ -43,25 +41,6 @@ LogisticRegressionFunction<MatType>::LogisticRegressionFunction(
}
}
template<typename MatType>
LogisticRegressionFunction<MatType>::LogisticRegressionFunction(
const MatType& predictors,
const arma::Row<size_t>& responses,
const arma::vec& initialPoint,
const double lambda) :
initialPoint(initialPoint),
// We promise to be well-behaved... the elements won't be modified.
predictors(math::MakeAlias(const_cast<MatType&>(predictors), false)),
responses(math::MakeAlias(const_cast<arma::Row<size_t>&>(responses),
false)),
lambda(lambda)
{
// To check if initialPoint is compatible with predictors.
if (initialPoint.n_rows != (predictors.n_rows + 1) ||
initialPoint.n_cols != 1)
this->initialPoint = arma::rowvec(predictors.n_rows + 1, arma::fill::zeros);
}
/**
* Shuffle the datapoints.
*/
@@ -87,8 +87,8 @@ double LogisticRegression<MatType>::Train(
lambda);
// Set size of parameters vector according to the input data received.
parameters = arma::rowvec(predictors.n_rows + 1, arma::fill::zeros);
errorFunction.InitialPoint() = parameters;
if (parameters.n_elem != predictors.n_rows + 1)
parameters = arma::rowvec(predictors.n_rows + 1, arma::fill::zeros);
Timer::Start("logistic_regression_optimization");
const double out = optimizer.Optimize(errorFunction, parameters,
@@ -22,12 +22,17 @@ using namespace mlpack;
using namespace mlpack::regression;
using namespace mlpack::util;
PROGRAM_INFO("L2-regularized Logistic Regression and Prediction",
// Short description.
// Program Name.
BINDING_NAME("L2-regularized Logistic Regression and Prediction");
// Short description.
BINDING_SHORT_DESC(
"An implementation of L2-regularized logistic regression for two-class "
"classification. Given labeled data, a model can be trained and saved for "
"future use; or, a pre-trained model can be used to classify new points.",
// Long description.
"future use; or, a pre-trained model can be used to classify new points.");
// Long description.
BINDING_LONG_DESC(
"An implementation of L2-regularized logistic regression using either the "
"L-BFGS optimizer or SGD (stochastic gradient descent). This solves the "
"regression problem"
@@ -92,8 +97,11 @@ PROGRAM_INFO("L2-regularized Logistic Regression and Prediction",
"\n\n"
"This implementation of logistic regression does not support the general "
"multi-class case but instead only the two-class case. Any labels must "
"be either 0 or 1. For more classes, see the softmax_regression program."
"\n\n"
"be either 0 or 1. For more classes, see the softmax_regression "
"program.");
// Example.
BINDING_EXAMPLE(
"As an example, to train a logistic regression model on the data '" +
PRINT_DATASET("data") + "' with labels '" + PRINT_DATASET("labels") + "' "
"with L2 regularization of 0.1, saving the model to '" +
@@ -107,13 +115,16 @@ PROGRAM_INFO("L2-regularized Logistic Regression and Prediction",
PRINT_DATASET("predictions") + "', the following command may be used: "
"\n\n" +
PRINT_CALL("logistic_regression", "input_model", "lr_model", "test", "test",
"output", "predictions"),
SEE_ALSO("@softmax_regression", "#softmax_regression"),
SEE_ALSO("@random_forest", "#random_forest"),
SEE_ALSO("Logistic regression on Wikipedia",
"https://en.wikipedia.org/wiki/Logistic_regression"),
SEE_ALSO("mlpack::regression::LogisticRegression C++ class documentation",
"@doxygen/classmlpack_1_1regression_1_1LogisticRegression.html"));
"output", "predictions"));
// See also...
BINDING_SEE_ALSO("@softmax_regression", "#softmax_regression");
BINDING_SEE_ALSO("@random_forest", "#random_forest");
BINDING_SEE_ALSO("Logistic regression on Wikipedia",
"https://en.wikipedia.org/wiki/Logistic_regression");
BINDING_SEE_ALSO("mlpack::regression::LogisticRegression C++ class "
"documentation",
"@doxygen/classmlpack_1_1regression_1_1LogisticRegression.html");
// Training parameters.
PARAM_MATRIX_IN("training", "A matrix containing the training set (the matrix "
+24 -16
View File
@@ -23,20 +23,26 @@ using namespace mlpack;
using namespace mlpack::neighbor;
using namespace mlpack::util;
// Information about the program itself.
PROGRAM_INFO("K-Approximate-Nearest-Neighbor Search with LSH",
// Short description.
// Program Name.
BINDING_NAME("K-Approximate-Nearest-Neighbor Search with LSH");
// Short description.
BINDING_SHORT_DESC(
"An implementation of approximate k-nearest-neighbor search with "
"locality-sensitive hashing (LSH). Given a set of reference points and a "
"set of query points, this will compute the k approximate nearest neighbors"
" of each query point in the reference set; models can be saved for future "
"use.",
// Long description.
"use.");
// Long description.
BINDING_LONG_DESC(
"This program will calculate the k approximate-nearest-neighbors of a set "
"of points using locality-sensitive hashing. You may specify a separate set"
" of reference points and query points, or just a reference set which will "
"be used as both the reference and query set. "
"\n\n"
"be used as both the reference and query set. ");
// Example.
BINDING_EXAMPLE(
"For example, the following will return 5 neighbors from the data for each "
"point in " + PRINT_DATASET("input") + " and store the distances in " +
PRINT_DATASET("distances") + " and the neighbors in " +
@@ -56,15 +62,17 @@ PROGRAM_INFO("K-Approximate-Nearest-Neighbor Search with LSH",
" parameter can be specified to set the random seed."
"\n\n"
"This program also has many other parameters to control its functionality;"
" see the parameter-specific documentation for more information.",
SEE_ALSO("@knn", "#knn"),
SEE_ALSO("@krann", "#krann"),
SEE_ALSO("Locality-sensitive hashing on Wikipedia",
"https://en.wikipedia.org/wiki/Locality-sensitive_hashing"),
SEE_ALSO("Locality-sensitive hashing scheme based on p-stable distributions"
" (pdf)", "http://mlpack.org/papers/lsh.pdf"),
SEE_ALSO("mlpack::neighbor::LSHSearch C++ class documentation",
"@doxygen/classmlpack_1_1neighbor_1_1LSHSearch.html"));
" see the parameter-specific documentation for more information.");
// See also...
BINDING_SEE_ALSO("@knn", "#knn");
BINDING_SEE_ALSO("@krann", "#krann");
BINDING_SEE_ALSO("Locality-sensitive hashing on Wikipedia",
"https://en.wikipedia.org/wiki/Locality-sensitive_hashing");
BINDING_SEE_ALSO("Locality-sensitive hashing scheme based on p-stable"
" distributions(pdf)", "http://mlpack.org/papers/lsh.pdf");
BINDING_SEE_ALSO("mlpack::neighbor::LSHSearch C++ class documentation",
"@doxygen/classmlpack_1_1neighbor_1_1LSHSearch.html");
// Define our input parameters that this program will take.
PARAM_MATRIX_IN("reference", "Matrix containing the reference dataset.", "r");
@@ -22,13 +22,17 @@ using namespace mlpack::kernel;
using namespace mlpack::util;
using namespace std;
// Define parameters for the executable.
PROGRAM_INFO("Mean Shift Clustering",
// Short description.
// Program Name.
BINDING_NAME("Mean Shift Clustering");
// Short description.
BINDING_SHORT_DESC(
"A fast implementation of mean-shift clustering using dual-tree range "
"search. Given a dataset, this uses the mean shift algorithm to produce "
"and return a clustering of the data.",
// Long description.
"and return a clustering of the data.");
// Long description.
BINDING_LONG_DESC(
"This program performs mean shift clustering on the given dataset, storing "
"the learned cluster assignments either as a column of labels in the input "
"dataset or separately."
@@ -42,22 +46,26 @@ PROGRAM_INFO("Mean Shift Clustering",
"\n\n"
"The output labels may be saved with the " + PRINT_PARAM_STRING("output") +
" output parameter and the centroids of each cluster may be saved with the"
" " + PRINT_PARAM_STRING("centroid") + " output parameter."
"\n\n"
" " + PRINT_PARAM_STRING("centroid") + " output parameter.");
// Example.
BINDING_EXAMPLE(
"For example, to run mean shift clustering on the dataset " +
PRINT_DATASET("data") + " and store the centroids to " +
PRINT_DATASET("centroids") + ", the following command may be used: "
"\n\n" +
PRINT_CALL("mean_shift", "input", "data", "centroid", "centroids"),
SEE_ALSO("@kmeans", "#kmeans"),
SEE_ALSO("@dbscan", "#dbscan"),
SEE_ALSO("Mean shift on Wikipedia",
"https://en.wikipedia.org/wiki/Mean_shift"),
SEE_ALSO("Mean Shift, Mode Seeking, and Clustering (pdf)",
PRINT_CALL("mean_shift", "input", "data", "centroid", "centroids"));
// See also...
BINDING_SEE_ALSO("@kmeans", "#kmeans");
BINDING_SEE_ALSO("@dbscan", "#dbscan");
BINDING_SEE_ALSO("Mean shift on Wikipedia",
"https://en.wikipedia.org/wiki/Mean_shift");
BINDING_SEE_ALSO("Mean Shift, Mode Seeking, and Clustering (pdf)",
"http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.510.1222"
"&rep=rep1&type=pdf"),
SEE_ALSO("mlpack::mean_shift::MeanShift C++ class documentation",
"@doxygen/classmlpack_1_1meanshift_1_1MeanShift.html"));
"&rep=rep1&type=pdf");
BINDING_SEE_ALSO("mlpack::mean_shift::MeanShift C++ class documentation",
"@doxygen/classmlpack_1_1meanshift_1_1MeanShift.html");
// Required options.
PARAM_MATRIX_IN_REQ("input", "Input dataset to perform clustering on.", "i");
+5 -1
View File
@@ -15,7 +15,11 @@
#include <mlpack/core/util/io.hpp>
#include "mvu.hpp"
PROGRAM_INFO("Maximum Variance Unfolding (MVU)", "This program implements "
// Program Name.
BINDING_NAME("Maximum Variance Unfolding (MVU)");
// Long description.
BINDING_LONG_DESC("This program implements "
"Maximum Variance Unfolding, a nonlinear dimensionality reduction "
"technique. The method minimizes dimensionality by unfolding a manifold "
"such that the distances to the nearest neighbors of each point are held "
+22 -13
View File
@@ -25,12 +25,17 @@ using namespace mlpack::util;
using namespace std;
using namespace arma;
PROGRAM_INFO("Parametric Naive Bayes Classifier",
// Short description.
// Program Name.
BINDING_NAME("Parametric Naive Bayes Classifier");
// Short description.
BINDING_SHORT_DESC(
"An implementation of the Naive Bayes Classifier, used for classification. "
"Given labeled data, an NBC model can be trained and saved, or, a "
"pre-trained model can be used for classification.",
// Long description.
"pre-trained model can be used for classification.");
// Long description.
BINDING_LONG_DESC(
"This program trains the Naive Bayes classifier on the given labeled "
"training set, or loads a model from the given model file, and then may use"
" that trained model to classify the points in a given test set."
@@ -60,8 +65,10 @@ PROGRAM_INFO("Parametric Naive Bayes Classifier",
"Note: the " + PRINT_PARAM_STRING("output") + " and " +
PRINT_PARAM_STRING("output_probs") + " parameters are deprecated and will "
"be removed in mlpack 4.0.0. Use " + PRINT_PARAM_STRING("predictions") +
" and " + PRINT_PARAM_STRING("probabilities") + " instead."
"\n\n"
" and " + PRINT_PARAM_STRING("probabilities") + " instead.");
// Example.
BINDING_EXAMPLE(
"For example, to train a Naive Bayes classifier on the dataset " +
PRINT_DATASET("data") + " with labels " + PRINT_DATASET("labels") + " "
"and save the model to " + PRINT_MODEL("nbc_model") + ", the following "
@@ -76,14 +83,16 @@ PROGRAM_INFO("Parametric Naive Bayes Classifier",
"may be used:"
"\n\n" +
PRINT_CALL("nbc", "input_model", "nbc_model", "test", "test_set", "output",
"predictions"),
SEE_ALSO("@softmax_regression", "#softmax_regression"),
SEE_ALSO("@random_forest", "#random_forest"),
SEE_ALSO("Naive Bayes classifier on Wikipedia",
"https://en.wikipedia.org/wiki/Naive_Bayes_classifier"),
SEE_ALSO("mlpack::naive_bayes::NaiveBayesClassifier C++ class "
"predictions"));
// See also...
BINDING_SEE_ALSO("@softmax_regression", "#softmax_regression");
BINDING_SEE_ALSO("@random_forest", "#random_forest");
BINDING_SEE_ALSO("Naive Bayes classifier on Wikipedia",
"https://en.wikipedia.org/wiki/Naive_Bayes_classifier");
BINDING_SEE_ALSO("mlpack::naive_bayes::NaiveBayesClassifier C++ class "
"documentation", "@doxygen/classmlpack_1_1naive__bayes_1_1"
"NaiveBayesClassifier.html"));
"NaiveBayesClassifier.html");
// A struct for saving the model with mappings.
struct NBCModel
+19 -13
View File
@@ -20,14 +20,18 @@
#include <ensmallen.hpp>
// Define parameters.
PROGRAM_INFO("Neighborhood Components Analysis (NCA)",
// Short description.
// Program Name.
BINDING_NAME("Neighborhood Components Analysis (NCA)");
// Short description.
BINDING_SHORT_DESC(
"An implementation of neighborhood components analysis, a distance learning"
" technique that can be used for preprocessing. Given a labeled dataset, "
"this uses NCA, which seeks to improve the k-nearest-neighbor "
"classification, and returns the learned distance metric.",
// Long description.
"classification, and returns the learned distance metric.");
// Long description.
BINDING_LONG_DESC(
"This program implements Neighborhood Components Analysis, both a linear "
"dimensionality reduction technique and a distance learning technique. The"
" method seeks to improve k-nearest-neighbor classification on a dataset "
@@ -88,15 +92,17 @@ PROGRAM_INFO("Neighborhood Components Analysis (NCA)",
"mlpack L-BFGS documentation (in lbfgs.hpp) or the vast set of published "
"literature on L-BFGS."
"\n\n"
"By default, the SGD optimizer is used.",
SEE_ALSO("@lmnn", "#lmnn"),
SEE_ALSO("Neighbourhood components analysis on Wikipedia",
"https://en.wikipedia.org/wiki/Neighbourhood_components_analysis"),
SEE_ALSO("Neighbourhood components analysis (pdf)",
"By default, the SGD optimizer is used.");
// See also...
BINDING_SEE_ALSO("@lmnn", "#lmnn");
BINDING_SEE_ALSO("Neighbourhood components analysis on Wikipedia",
"https://en.wikipedia.org/wiki/Neighbourhood_components_analysis");
BINDING_SEE_ALSO("Neighbourhood components analysis (pdf)",
"http://papers.nips.cc/paper/2566-neighbourhood-components-"
"analysis.pdf"),
SEE_ALSO("mlpack::nca::NCA C++ class documentation",
"@doxygen/classmlpack_1_1nca_1_1NCA.html"));
"analysis.pdf");
BINDING_SEE_ALSO("mlpack::nca::NCA C++ class documentation",
"@doxygen/classmlpack_1_1nca_1_1NCA.html");
PARAM_MATRIX_IN_REQ("input", "Input dataset to run NCA on.", "i");
PARAM_MATRIX_OUT("output", "Output matrix for learned distance matrix.", "o");
+22 -14
View File
@@ -32,19 +32,25 @@ using namespace mlpack::util;
// Convenience typedef.
typedef NSModel<FurthestNS> KFNModel;
// Information about the program itself.
PROGRAM_INFO("k-Furthest-Neighbors Search",
// Short description.
// Program Name.
BINDING_NAME("k-Furthest-Neighbors Search");
// Short description.
BINDING_SHORT_DESC(
"An implementation of k-furthest-neighbor search using single-tree and "
"dual-tree algorithms. Given a set of reference points and query points, "
"this can find the k furthest neighbors in the reference set of each query"
" point using trees; trees that are built can be saved for future use.",
// Long description.
" point using trees; trees that are built can be saved for future use.");
// Long description.
BINDING_LONG_DESC(
"This program will calculate the k-furthest-neighbors of a set of "
"points. You may specify a separate set of reference points and query "
"points, or just a reference set which will be used as both the reference "
"and query set."
"\n\n"
"and query set.");
// Example.
BINDING_EXAMPLE(
"For example, the following will calculate the 5 furthest neighbors of each"
"point in " + PRINT_DATASET("input") + " and store the distances in " +
PRINT_DATASET("distances") + " and the neighbors in " +
@@ -57,13 +63,15 @@ PROGRAM_INFO("k-Furthest-Neighbors Search",
"neighbors output matrix corresponds to the index of the point in the "
"reference set which is the j'th furthest neighbor from the point in the "
"query set with index i. Row i and column j in the distances output file "
"corresponds to the distance between those two points.",
SEE_ALSO("@approx_kfn", "#approx_kfn"),
SEE_ALSO("@knn", "#knn"),
SEE_ALSO("Tree-independent dual-tree algorithms (pdf)",
"http://proceedings.mlr.press/v28/curtin13.pdf"),
SEE_ALSO("mlpack::neighbor::NeighborSearch C++ class documentation",
"@doxygen/classmlpack_1_1neighbor_1_1NeighborSearch.html"));
"corresponds to the distance between those two points.");
// See also...
BINDING_SEE_ALSO("@approx_kfn", "#approx_kfn");
BINDING_SEE_ALSO("@knn", "#knn");
BINDING_SEE_ALSO("Tree-independent dual-tree algorithms (pdf)",
"http://proceedings.mlr.press/v28/curtin13.pdf");
BINDING_SEE_ALSO("mlpack::neighbor::NeighborSearch C++ class documentation",
"@doxygen/classmlpack_1_1neighbor_1_1NeighborSearch.html");
// Define our input parameters that this program will take.
PARAM_MATRIX_IN("reference", "Matrix containing the reference dataset.", "r");
+25 -17
View File
@@ -34,20 +34,26 @@ using namespace mlpack::util;
// Convenience typedef.
typedef NSModel<NearestNeighborSort> KNNModel;
// Information about the program itself.
PROGRAM_INFO("k-Nearest-Neighbors Search",
// Short description.
// Program Name.
BINDING_NAME("k-Nearest-Neighbors Search");
// Short description.
BINDING_SHORT_DESC(
"An implementation of k-nearest-neighbor search using single-tree and "
"dual-tree algorithms. Given a set of reference points and query points, "
"this can find the k nearest neighbors in the reference set of each query "
"point using trees; trees that are built can be saved for future use.",
// Long description.
"point using trees; trees that are built can be saved for future use.");
// Long description.
BINDING_LONG_DESC(
"This program will calculate the k-nearest-neighbors of a set of "
"points using kd-trees or cover trees (cover tree support is experimental "
"and may be slow). You may specify a separate set of "
"reference points and query points, or just a reference set which will be "
"used as both the reference and query set."
"\n\n"
"used as both the reference and query set.");
// Example.
BINDING_EXAMPLE(
"For example, the following command will calculate the 5 nearest neighbors "
"of each point in " + PRINT_DATASET("input") + " and store the distances "
"in " + PRINT_DATASET("distances") + " and the neighbors in " +
@@ -60,16 +66,18 @@ PROGRAM_INFO("k-Nearest-Neighbors Search",
"output matrix corresponds to the index of the point in the reference set "
"which is the j'th nearest neighbor from the point in the query set with "
"index i. Row j and column i in the distances output matrix corresponds to"
" the distance between those two points.",
SEE_ALSO("@lsh", "#lsh"),
SEE_ALSO("@krann", "#krann"),
SEE_ALSO("@kfn", "#kfn"),
SEE_ALSO("NeighborSearch tutorial (k-nearest-neighbors)",
"@doxygen/nstutorial.html"),
SEE_ALSO("Tree-independent dual-tree algorithms (pdf)",
"http://proceedings.mlr.press/v28/curtin13.pdf"),
SEE_ALSO("mlpack::neighbor::NeighborSearch C++ class documentation",
"@doxygen/classmlpack_1_1neighbor_1_1NeighborSearch.html"));
" the distance between those two points.");
// See also...
BINDING_SEE_ALSO("@lsh", "#lsh");
BINDING_SEE_ALSO("@krann", "#krann");
BINDING_SEE_ALSO("@kfn", "#kfn");
BINDING_SEE_ALSO("NeighborSearch tutorial (k-nearest-neighbors)",
"@doxygen/nstutorial.html");
BINDING_SEE_ALSO("Tree-independent dual-tree algorithms (pdf)",
"http://proceedings.mlr.press/v28/curtin13.pdf");
BINDING_SEE_ALSO("mlpack::neighbor::NeighborSearch C++ class documentation",
"@doxygen/classmlpack_1_1neighbor_1_1NeighborSearch.html");
// Define our input parameters that this program will take.
PARAM_MATRIX_IN("reference", "Matrix containing the reference dataset.", "r");
+25 -17
View File
@@ -27,12 +27,16 @@ using namespace mlpack::amf;
using namespace mlpack::util;
using namespace std;
// Document program.
PROGRAM_INFO("Non-negative Matrix Factorization",
// Short description.
// Program Name.
BINDING_NAME("Non-negative Matrix Factorization");
// Short description.
BINDING_SHORT_DESC(
"An implementation of non-negative matrix factorization. This can be used "
"to decompose an input dataset into two low-rank non-negative components.",
// Long description.
"to decompose an input dataset into two low-rank non-negative components.");
// Long description.
BINDING_LONG_DESC(
"This program performs non-negative matrix factorization on the given "
"dataset, storing the resulting decomposed matrices in the specified "
"files. For an input dataset V, NMF decomposes V into two matrices W "
@@ -57,25 +61,29 @@ PROGRAM_INFO("Non-negative Matrix Factorization",
"The maximum number of iterations is specified with " +
PRINT_PARAM_STRING("max_iterations") + ", and the minimum residue "
"required for algorithm termination is specified with the " +
PRINT_PARAM_STRING("min_residue") + " parameter."
"\n\n"
PRINT_PARAM_STRING("min_residue") + " parameter.");
// Example.
BINDING_EXAMPLE(
"For example, to run NMF on the input matrix " + PRINT_DATASET("V") + " "
"using the 'multdist' update rules with a rank-10 decomposition and "
"storing the decomposed matrices into " + PRINT_DATASET("W") + " and " +
PRINT_DATASET("H") + ", the following command could be used: "
"\n\n" +
PRINT_CALL("nmf", "input", "V", "w", "W", "h", "H", "rank", 10,
"update_rules", "multdist"),
SEE_ALSO("@cf", "#cf"),
SEE_ALSO("Alternating matrix factorization tutorial",
"@doxygen/amftutorial.html"),
SEE_ALSO("Non-negative matrix factorization on Wikipedia",
"https://en.wikipedia.org/wiki/Non-negative_matrix_factorization"),
SEE_ALSO("Algorithms for non-negative matrix factorization (pdf)",
"update_rules", "multdist"));
// See also...
BINDING_SEE_ALSO("@cf", "#cf");
BINDING_SEE_ALSO("Alternating matrix factorization tutorial",
"@doxygen/amftutorial.html");
BINDING_SEE_ALSO("Non-negative matrix factorization on Wikipedia",
"https://en.wikipedia.org/wiki/Non-negative_matrix_factorization");
BINDING_SEE_ALSO("Algorithms for non-negative matrix factorization (pdf)",
"http://papers.nips.cc/paper/1861-algorithms-for-non-negative-matrix-"
"factorization.pdf"),
SEE_ALSO("mlpack::amf::AMF C++ class documentation",
"@doxygen/classmlpack_1_1amf_1_1AMF.html"));
"factorization.pdf");
BINDING_SEE_ALSO("mlpack::amf::AMF C++ class documentation",
"@doxygen/classmlpack_1_1amf_1_1AMF.html");
// Parameters for program.
PARAM_MATRIX_IN_REQ("input", "Input dataset to perform NMF on.", "i");

Some files were not shown because too many files have changed in this diff Show More