Minor changes and fixes.
This commit is contained in:
+54
-75
@@ -1,4 +1,5 @@
|
||||
# Documentation for mlpack
|
||||
|
||||
## A fast, flexible machine learning library
|
||||
|
||||
mlpack is an intuitive, fast, and flexible header-only C++ machine learning
|
||||
@@ -18,22 +19,21 @@ _If you use mlpack, please [cite the software](citation.md)._
|
||||
|
||||
Installing mlpack can be done using the
|
||||
[instructions in the README](README.md#3-installing-and-using-mlpack-in-c);
|
||||
or the [Windows build guide](user/build_windows.md). Then, the following
|
||||
simple guides are good places to get started:
|
||||
or the [Windows build guide](user/build_windows.md).
|
||||
The following basic guides are *highly recommended* before using mlpack.
|
||||
|
||||
* [mlpack C++ quickstart](quickstart/cpp.md): create a couple simple C++
|
||||
programs that use mlpack
|
||||
* [Sample Windows mlpack C++ application](user/sample_ml_app.md): create a
|
||||
working mlpack Windows program using Visual Studio
|
||||
* ***First steps***:
|
||||
- [mlpack C++ quickstart](quickstart/cpp.md): create a couple simple C++
|
||||
programs that use mlpack
|
||||
- [Sample Windows mlpack C++ application](user/sample_ml_app.md): create a
|
||||
working mlpack Windows program using Visual Studio
|
||||
|
||||
After that, it's a good idea to familiarize yourself with the basics of the
|
||||
library. The documentation for mlpack's algorithms depends on the concepts in
|
||||
the pages below.
|
||||
* ***Basics of matrices and data in mlpack***:
|
||||
- [Matrices and data in mlpack](user/matrices.md)
|
||||
- [Loading and saving mlpack objects](user/load_save.md)
|
||||
|
||||
* [Matrices and data in mlpack](user/matrices.md)
|
||||
* [Loading and saving mlpack objects](user/load_save.md)
|
||||
* [Core mlpack documentation](user/core.md): reference documentation for all
|
||||
core classes and functions that are used in mlpack.
|
||||
* ***Reference for mlpack core classes***:
|
||||
- [Core mlpack documentation](user/core.md)
|
||||
|
||||
## mlpack algorithm documentation
|
||||
|
||||
@@ -53,68 +53,6 @@ detailed in the sections below.
|
||||
* [Modeling utilities](#modeling-utilities): cross-validation, hyperparameter
|
||||
tuning, etc.
|
||||
|
||||
## Bindings to other languages
|
||||
|
||||
mlpack's bindings to other languages have less complete functionality than
|
||||
mlpack in C++, but almost all of the same algorithms are available.
|
||||
|
||||
***Python***:
|
||||
|
||||
* [Python quickstart](quickstart/python.md)
|
||||
* [Python reference documentation](https://www.mlpack.org/doc/python_documentation.html)
|
||||
|
||||
***Julia***:
|
||||
|
||||
* [Julia quickstart](quickstart/julia.md)
|
||||
* [Julia reference documentation](https://www.mlpack.org/doc/julia_documentation.html)
|
||||
|
||||
***R***:
|
||||
|
||||
* [R quickstart](quickstart/r.md)
|
||||
* [R reference documentation](https://www.mlpack.org/doc/r_documentation.html)
|
||||
|
||||
***Command-line programs***:
|
||||
|
||||
* [Command-line quickstart](quickstart/cli.md)
|
||||
* [Command-line reference documentation](https://www.mlpack.org/doc/cli_documentation.html)
|
||||
|
||||
***Go***:
|
||||
|
||||
* [Go quickstart](quickstart/go.md)
|
||||
* [Go reference documentation](https://www.mlpack.org/doc/go_documentation.html)
|
||||
|
||||
## Examples and further documentation
|
||||
|
||||
* [mlpack examples repository](https://github.com/mlpack/examples/): numerous
|
||||
fully-working example applications of mlpack, in C++ and other languages.
|
||||
* [mlpack models repository](https://github.com/mlpack/models/): complex models
|
||||
in C++ built with mlpack
|
||||
|
||||
For additional documentation beyond what is covered in all the resources above,
|
||||
the source code should be consulted. Each method is fully documented.
|
||||
|
||||
## Developer documentation
|
||||
|
||||
Throughout the codebase, mlpack uses some common template parameter policies.
|
||||
These are documented below.
|
||||
|
||||
* [The `ElemType` policy](developer/elemtype.md): element types for data
|
||||
* [The `MetricType` policy](developer/metrics.md): distance metrics
|
||||
* [The `KernelType` policy](developer/kernels.md): kernel functions
|
||||
* [The `TreeType` policy](developer/trees.md): space trees (ball trees,
|
||||
KD-trees, etc.)
|
||||
|
||||
In addition, the following documentation may be useful when developing bindings
|
||||
for other languages:
|
||||
|
||||
* [Timers](developer/timer.md): timing parts of bindings
|
||||
* [Writing an mlpack binding](developer/iodoc.md): simple examples of mlpack
|
||||
bindings
|
||||
* [Automatic bindings](developer/bindings.md): details on mlpack's automatic
|
||||
binding generator system.
|
||||
|
||||
## Algorithm documentation
|
||||
|
||||
### Classification algorithms
|
||||
|
||||
Classify points as discrete labels (`0`, `1`, `2`, ...).
|
||||
@@ -164,3 +102,44 @@ Transform data from one space to another.
|
||||
Cross-validation, hyperparameter tuning, etc.
|
||||
|
||||
<!-- TODO: add some -->
|
||||
|
||||
## Bindings to other languages
|
||||
|
||||
mlpack's bindings to other languages have less complete functionality than
|
||||
mlpack in C++, but almost all the same algorithms are available.
|
||||
|
||||
| ***Python*** | -- | [quickstart](quickstart/python.md) | -- | [reference](https://www.mlpack.org/doc/python_documentation.html) |
|
||||
| ***Julia*** | -- | [quickstart](quickstart/julia.md) | -- | [reference](https://www.mlpack.org/doc/julia_documentation.html) |
|
||||
| ***R*** | -- | [quickstart](quickstart/r.md) | -- | [reference](https://www.mlpack.org/doc/r_documentation.html)
|
||||
| ***Command-line programs*** | -- | [quickstart](quickstart/cli.md) | -- | [reference](https://www.mlpack.org/doc/cli_documentation.html) |
|
||||
| ***Go*** | -- | [quickstart](quickstart/go.md) | -- | [reference](https://www.mlpack.org/doc/go_documentation.html) |
|
||||
|
||||
## Examples and further documentation
|
||||
|
||||
* [mlpack examples repository](https://github.com/mlpack/examples/): numerous
|
||||
fully-working example applications of mlpack, in C++ and other languages.
|
||||
* [mlpack models repository](https://github.com/mlpack/models/): complex models
|
||||
in C++ built with mlpack
|
||||
|
||||
For additional documentation beyond what is covered in all the resources above,
|
||||
the source code should be consulted. Each method is fully documented.
|
||||
|
||||
## Developer documentation
|
||||
|
||||
Throughout the codebase, mlpack uses some common template parameter policies.
|
||||
These are documented below.
|
||||
|
||||
* [The `ElemType` policy](developer/elemtype.md): element types for data
|
||||
* [The `MetricType` policy](developer/metrics.md): distance metrics
|
||||
* [The `KernelType` policy](developer/kernels.md): kernel functions
|
||||
* [The `TreeType` policy](developer/trees.md): space trees (ball trees,
|
||||
KD-trees, etc.)
|
||||
|
||||
In addition, the following documentation may be useful when developing bindings
|
||||
for other languages:
|
||||
|
||||
* [Timers](developer/timer.md): timing parts of bindings
|
||||
* [Writing an mlpack binding](developer/iodoc.md): simple examples of mlpack
|
||||
bindings
|
||||
* [Automatic bindings](developer/bindings.md): details on mlpack's automatic
|
||||
binding generator system.
|
||||
|
||||
+156
-30
@@ -4,24 +4,42 @@ Underlying the implementations of [mlpack's machine learning
|
||||
algorithms](index.md#mlpack-algorithm-documentation) are mlpack core support
|
||||
classes, each of which are documented on this page.
|
||||
|
||||
* [Core math utilities](#core-math-utilities): utility classes for mathematical
|
||||
purposes
|
||||
* [Distributions](#distributions): probability distributions
|
||||
* [Metrics](#metrics): distance metrics for geometric algorithms
|
||||
* [Kernels](#kernels): Mercer kernels for kernel-based algorithms
|
||||
|
||||
## Core math utilities
|
||||
|
||||
Utilities in the `mlpack::math::` namespace are meant to provide additional
|
||||
mathematical support on top of Armadillo.
|
||||
|
||||
* [`math::Range`](#mathrange): simple mathematical range (i.e. `[0, 3]`)
|
||||
|
||||
---
|
||||
|
||||
### `math::Range`
|
||||
|
||||
The `math::Range` class represents a simple mathematical range (i.e. `[0, 3]`),
|
||||
with each value represented as a `double`.
|
||||
with the bounds represented as `double`s.
|
||||
|
||||
---
|
||||
|
||||
#### Constructors
|
||||
|
||||
* `r = math::Range()`
|
||||
- Construct an empty range.
|
||||
|
||||
* `r = math::Range(p)`
|
||||
- Construct the range `[p, p]`.
|
||||
|
||||
* `r = math::Range(lo, hi)`
|
||||
- Construct a range. If no value is specified, the range is empty; if `p` is
|
||||
specified, the range is `[p, p]`; if `lo` and `hi` are specified, the range
|
||||
is `[lo, hi]`.
|
||||
- Construct the range `[lo, hi]`.
|
||||
|
||||
---
|
||||
|
||||
#### Accessing and modifying range properties
|
||||
|
||||
* `r.Lo()` and `r.Hi()` return the lower and upper bounds of the range as
|
||||
`double`s.
|
||||
@@ -33,6 +51,10 @@ with each value represented as a `double`.
|
||||
|
||||
* `r.Mid()` returns the midpoint of the range as a `double`.
|
||||
|
||||
---
|
||||
|
||||
#### Working with ranges
|
||||
|
||||
* Given two ranges `r1` and `r2`,
|
||||
- `r1 | r2` returns the union of the ranges,
|
||||
- `r1 |= r2` expands `r1` to include the range `r2`,
|
||||
@@ -50,24 +72,34 @@ with each value represented as a `double`.
|
||||
- `r *= d` scales `r.Lo()` and `r.Hi()` by `d`, and
|
||||
- `r.Contains(d)` returns `true` if `d` is contained in the range.
|
||||
|
||||
---
|
||||
|
||||
* To use ranges with different element types (e.g. `float`), use the type
|
||||
`math::RangeType<float>` or similar.
|
||||
|
||||
---
|
||||
|
||||
Example:
|
||||
|
||||
```c++
|
||||
math::Range r1(5.0, 6.0); // [5, 6]
|
||||
math::Range r2(7.0, 8.0); // [7, 8]
|
||||
mlpack::math::Range r1(5.0, 6.0); // [5, 6]
|
||||
mlpack::math::Range r2(7.0, 8.0); // [7, 8]
|
||||
|
||||
math::Range r3 = r1 | r2; // [5, 8]
|
||||
math::Range r4 = r1 & r2; // empty range
|
||||
mlpack::math::Range r3 = r1 | r2; // [5, 8]
|
||||
mlpack::math::Range r4 = r1 & r2; // empty range
|
||||
|
||||
bool b1 = r1.Contains(r2); // false
|
||||
bool b2 = r1.Contains(5.5); // true
|
||||
bool b3 = r1.Contains(r3); // true
|
||||
bool b4 = r3.Contains(r4); // false
|
||||
|
||||
// Create a range of `float`s and a range of `int`s.
|
||||
mlpack::math::RangeType<float> r5(1.0f, 1.5f); // [1.0, 1.5]
|
||||
mlpack::math::RangeType<int> r6(3, 4); // [3, 4]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
`math::Range` is used by:
|
||||
|
||||
* [`RangeSearch`](range_search.md)
|
||||
@@ -80,11 +112,16 @@ bool b4 = r3.Contains(r4); // false
|
||||
mlpack has support for a number of different distributions, each supporting the
|
||||
same API. These can be used with, for instance, the [`HMM`](hmm.md) class.
|
||||
|
||||
* [`DiscreteDistribution`](#discretedistribution): multidimensional categorical
|
||||
distribution (generalized Bernoulli distribution)
|
||||
* [`GaussianDistribution`](#gaussiandistribution): multidimensional Gaussian
|
||||
distribution
|
||||
|
||||
### `DiscreteDistribution`
|
||||
|
||||
`DiscreteDistribution` represents a multidimensional categorical distribution
|
||||
(or generalized Bernoulli distribution) where integer-valued vectors (e.g. `[0,
|
||||
3, 4]`) are associated with specific probabilities in each dimension.
|
||||
(or generalized Bernoulli distribution) where integer-valued vectors (e.g.
|
||||
`[0, 3, 4]`) are associated with specific probabilities in each dimension.
|
||||
|
||||
*Example:* a 3-dimensional `DiscreteDistribution` will have a specific
|
||||
probability value associated with each integer value in each dimension. So, for
|
||||
@@ -92,6 +129,10 @@ the vector `[0, 3, 4]`, `P(0)` in dimension 0 could be, e.g., `0.3`, `P(3)` in
|
||||
dimension 1 could be, e.g., `0.4`, and `P(4)` in dimension 2 could be, e.g.,
|
||||
`0.6`. Then, `P([0, 3, 4])` would be `0.3 * 0.4 * 0.6 = 0.072`.
|
||||
|
||||
---
|
||||
|
||||
#### Constructors
|
||||
|
||||
* `d = DiscreteDistribution(numObservations)`
|
||||
- Create a one-dimensional discrete distribution with `numObservations`
|
||||
different observations in the one and only dimension. `numObservations` is
|
||||
@@ -112,10 +153,14 @@ dimension 1 could be, e.g., `0.4`, and `P(4)` in dimension 2 could be, e.g.,
|
||||
- `probabilities[i]` is a vector such that `probabilities[i][j]` contains the
|
||||
probability of `j` in dimension `i`.
|
||||
|
||||
---
|
||||
|
||||
#### Access and modify properties of distribution
|
||||
|
||||
* `d.Dimensionality()` returns a `size_t` indicating the number of dimensions
|
||||
in the multidimensional discrete distribution.
|
||||
|
||||
* `d.Probabilities(i)` returns an `arma::vec` containing the probabilities of
|
||||
* `d.Probabilities(i)` returns an `arma::vec&` containing the probabilities of
|
||||
each observation in dimension `i`.
|
||||
- `d.Probabilities(i)[j]` is the probability of `j` in dimension `i`.
|
||||
- This can be used to modify probabilities: `d.Probabilities(0)[1] = 0.7`
|
||||
@@ -123,6 +168,10 @@ dimension 1 could be, e.g., `0.4`, and `P(4)` in dimension 2 could be, e.g.,
|
||||
- *Note:* when setting probabilities manually, be sure that the sum of
|
||||
probabilities in a dimension is 1!
|
||||
|
||||
---
|
||||
|
||||
#### Compute probabilities of points
|
||||
|
||||
* `d.Probability(observation)` returns the probability of the given
|
||||
observation as a `double`.
|
||||
- `observation` should be an `arma::vec` of size `d.Dimensionality()`.
|
||||
@@ -142,9 +191,17 @@ dimension 1 could be, e.g., `0.4`, and `P(4)` in dimension 2 could be, e.g.,
|
||||
* `d.LogProbability(observations, probabilities)` computes the
|
||||
log-probabilities of many observations.
|
||||
|
||||
---
|
||||
|
||||
#### Sample from the distribution
|
||||
|
||||
* `d.Random()` returns an `arma::vec` with a random sample from the
|
||||
multidimensional discrete distribution.
|
||||
|
||||
---
|
||||
|
||||
#### Fit the distribution to observations
|
||||
|
||||
* `d.Train(observations)`
|
||||
- Fit the distribution to the given observations.
|
||||
- `observations` should be an `arma::mat` with number of rows equal to
|
||||
@@ -160,11 +217,13 @@ dimension 1 could be, e.g., `0.4`, and `P(4)` in dimension 2 could be, e.g.,
|
||||
- `observationProbabilities[i]` should be equal to the probability that
|
||||
`observations.col(i)` is from `d`.
|
||||
|
||||
---
|
||||
|
||||
*Example usage:*
|
||||
|
||||
```c++
|
||||
// Create a single-dimension Bernoulli distribution: P([0]) = 0.3, P([1]) = 0.7.
|
||||
DiscreteDistribution bernoulli(2);
|
||||
mlpack::DiscreteDistribution bernoulli(2);
|
||||
bernoulli.Probabilities(0)[0] = 0.3;
|
||||
bernoulli.Probabilities(0)[1] = 0.7;
|
||||
|
||||
@@ -177,7 +236,7 @@ arma::vec probDim0 = arma::vec("0.1 0.3 0.5 0.1"); // 4 possible values.
|
||||
arma::vec probDim1 = arma::vec("0.7 0.3"); // 2 possible values.
|
||||
arma::vec probDim2 = arma::vec("0.4 0.4 0.2"); // 3 possible values.
|
||||
std::vector<arma::vec> probs { probDim0, probDim1, probDim2 };
|
||||
DiscreteDistribution d(probs);
|
||||
mlpack::DiscreteDistribution d(probs);
|
||||
|
||||
arma::vec obs("2 0 1");
|
||||
const double p3 = d.Probability(obs); // p3 = 0.5 * 0.7 * 0.4 = 0.14.
|
||||
@@ -185,11 +244,12 @@ const double p3 = d.Probability(obs); // p3 = 0.5 * 0.7 * 0.4 = 0.14.
|
||||
// Estimate a 10-dimensional discrete distribution.
|
||||
// Each dimension takes values between 0 and 9.
|
||||
arma::mat observations = arma::randi<arma::mat>(10, 1000,
|
||||
arma::distr_param(0, 10));
|
||||
arma::distr_param(0, 9));
|
||||
|
||||
// Create a distribution with 10 observations in each of the 10 dimensions.
|
||||
DiscreteDistribution d2(arma::Col<size_t>("10 10 10 10 10 10 10 10 10 10"));
|
||||
d2.Estimate(observations);
|
||||
mlpack::DiscreteDistribution d2(
|
||||
arma::Col<size_t>("10 10 10 10 10 10 10 10 10 10"));
|
||||
d2.Train(observations);
|
||||
|
||||
// Compute the probabilities of each point.
|
||||
arma::vec probabilities;
|
||||
@@ -205,6 +265,10 @@ std::cout << "Average probability: " << arma::mean(probabilities) << "."
|
||||
`GaussianDistribution` is a standard multivariate Gaussian distribution with
|
||||
parameterized mean and covariance.
|
||||
|
||||
---
|
||||
|
||||
#### Constructors
|
||||
|
||||
* `g = GaussianDistribution(dimensionality)`
|
||||
- Create the distribution with the given dimensionality.
|
||||
- The distribution will have a zero mean and unit diagonal covariance matrix.
|
||||
@@ -216,6 +280,10 @@ parameterized mean and covariance.
|
||||
- `covariance` is of type `arma::mat`, and should be symmetric and square,
|
||||
with rows and columns equal to the dimensionality of the distribution.
|
||||
|
||||
---
|
||||
|
||||
#### Access and modify properties of distribution
|
||||
|
||||
* `g.Dimensionality()` returns the dimensionality of the distribution as a
|
||||
`size_t`.
|
||||
|
||||
@@ -232,6 +300,10 @@ parameterized mean and covariance.
|
||||
* `g.LogDetCov()` returns a `double` holding the log-determinant of the
|
||||
covariance.
|
||||
|
||||
---
|
||||
|
||||
#### Compute probabilities of points
|
||||
|
||||
* `g.Probability(observation)` returns the probability of the given
|
||||
observation as a `double`.
|
||||
- `observation` should be an `arma::vec` of size `d.Dimensionality()`.
|
||||
@@ -249,9 +321,17 @@ parameterized mean and covariance.
|
||||
* `g.LogProbability(observations, probabilities)` computes the
|
||||
log-probabilities of many observations.
|
||||
|
||||
---
|
||||
|
||||
#### Sample from the distribution
|
||||
|
||||
* `g.Random()` returns an `arma::vec` with a random sample from the
|
||||
multidimensional discrete distribution.
|
||||
|
||||
---
|
||||
|
||||
#### Fit the distribution to observations
|
||||
|
||||
* `g.Train(observations)`
|
||||
- Fit the distribution to the given observations.
|
||||
- `observations` should be an `arma::mat` with number of rows equal to
|
||||
@@ -272,7 +352,7 @@ parameterized mean and covariance.
|
||||
```c++
|
||||
// Create a Gaussian distribution in 3 dimensions with zero mean and unit
|
||||
// covariance.
|
||||
GaussianDistribution g(3);
|
||||
mlpack::GaussianDistribution g(3);
|
||||
|
||||
// Compute the probability of the point [0, 0.5, 0.25].
|
||||
const double p = g.Probability(arma::vec("0 0.5 0.25"));
|
||||
@@ -292,7 +372,7 @@ const double p2 = g.Probability(arma::vec("0 0.5 0.25"));
|
||||
// dimensions.
|
||||
arma::mat samples(50, 10000, arma::fill::randn); // Normally distributed.
|
||||
|
||||
GaussianDistribution g2(50);
|
||||
mlpack::GaussianDistribution g2(50);
|
||||
g2.Train(samples);
|
||||
|
||||
// Compute the probability of all of the samples.
|
||||
@@ -320,6 +400,12 @@ including:
|
||||
* [`RANN`](rann.md)
|
||||
* [`KMeans`](kmeans.md)
|
||||
|
||||
Supported metrics:
|
||||
|
||||
* [`LMetric`](#lmetric): generalized L-metric/Lp-metric, including
|
||||
Manhattan/Euclidean/Chebyshev distances
|
||||
* [Implement a custom metric](../developer/metrics.md)
|
||||
|
||||
### `LMetric`
|
||||
|
||||
The `LMetric` template class implements a [generalized
|
||||
@@ -341,6 +427,8 @@ LMetric<Power, TakeRoot>
|
||||
- If set to `false`, the metric will no longer satisfy the triangle
|
||||
inequality.
|
||||
|
||||
---
|
||||
|
||||
Several convenient typedefs are available:
|
||||
|
||||
* `ManhattanDistance` (defined as `LMetric<1>`)
|
||||
@@ -348,6 +436,8 @@ Several convenient typedefs are available:
|
||||
* `SquaredEuclideanDistance` (defined as `LMetric<2, false>`)
|
||||
* `ChebyshevDistance` (defined as `LMetric<INT_MAX>`)
|
||||
|
||||
---
|
||||
|
||||
The static `Evaluate()` method can be used to compute the distance between two
|
||||
vectors.
|
||||
|
||||
@@ -363,23 +453,36 @@ implements the Armadillo API (e.g. `arma::fvec`, `arma::sp_fvec`, etc.).
|
||||
arma::vec a("0.0 1.0 5.0");
|
||||
arma::vec b("1.0 3.0 5.0");
|
||||
|
||||
const double d1 = ManhattanDistance::Evaluate(a, b); // d1 = 3.0
|
||||
const double d2 = EuclideanDistance::Evaluate(a, b); // d2 = 2.236
|
||||
const double d3 = SquaredEuclideanDistance::Evaluate(a, b); // d3 = 5.0
|
||||
const double d4 = ChebyshevDistance::Evaluate(a, b); // d4 = 2.0
|
||||
const double d5 = LMetric<4>::Evaluate(a, b); // d5 = 2.0305
|
||||
const double d6 = LMetric<3, false>::Evaluate(a, b); // d6 = 9.0
|
||||
const double d1 = mlpack::ManhattanDistance::Evaluate(a, b); // d1 = 3.0
|
||||
const double d2 = mlpack::EuclideanDistance::Evaluate(a, b); // d2 = 2.24
|
||||
const double d3 = mlpack::SquaredEuclideanDistance::Evaluate(a, b); // d3 = 5.0
|
||||
const double d4 = mlpack::ChebyshevDistance::Evaluate(a, b); // d4 = 2.0
|
||||
const double d5 = mlpack::LMetric<4>::Evaluate(a, b); // d5 = 2.03
|
||||
const double d6 = mlpack::LMetric<3, false>::Evaluate(a, b); // d6 = 9.0
|
||||
|
||||
std::cout << "Manhattan distance: " << d1 << "." << std::endl;
|
||||
std::cout << "Euclidean distance: " << d2 << "." << std::endl;
|
||||
std::cout << "Squared Euclidean distance: " << d3 << "." << std::endl;
|
||||
std::cout << "Chebyshev distance: " << d4 << "." << std::endl;
|
||||
std::cout << "L4-distance: " << d5 << "." << std::endl;
|
||||
std::cout << "Cubed L3-distance: " << d6 << "." << std::endl;
|
||||
|
||||
// Compute the distance between two random 10-dimensional vectors in a matrix.
|
||||
arma::mat m(10, 100, arma::fill::randu);
|
||||
|
||||
const double d7 = EuclideanDistance::Evaluate(m.col(0), m.col(7));
|
||||
const double d7 = mlpack::EuclideanDistance::Evaluate(m.col(0), m.col(7));
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Distance between two random vectors: " << d7 << "." << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// Compute the distance between two 32-bit precision `float` vectors.
|
||||
arma::fvec fa("0.0 1.0 5.0");
|
||||
arma::fvec fb("1.0 3.0 5.0");
|
||||
|
||||
const double d8 = EuclideanDistance::Evaluate(fa, fb); // d8 = 2.236
|
||||
const double d8 = mlpack::EuclideanDistance::Evaluate(fa, fb); // d8 = 2.236
|
||||
|
||||
std::cout << "Euclidean distance (fvec): " << d8 << "." << std::endl;
|
||||
```
|
||||
|
||||
## Kernels
|
||||
@@ -397,6 +500,12 @@ including:
|
||||
* [`FastMKS`](fastmks.md)
|
||||
* [`NystroemMethod`](nystroem_method.md)
|
||||
|
||||
Supported kernels:
|
||||
|
||||
* [`GaussianKernel`](#gaussiankernel): standard Gaussian/radial basis
|
||||
function/RBF kernel
|
||||
* [Implement a custom kernel](../developer/kernels.md)
|
||||
|
||||
### `GaussianKernel`
|
||||
|
||||
The `GaussianKernel` class implements the standard [Gaussian
|
||||
@@ -407,12 +516,20 @@ The Gaussian kernel is defined as:
|
||||
`k(x1, x2) = exp(-|| x1 - x2 ||^2 / (2 * bw^2))`
|
||||
where `bw` is the bandwidth parameter of the kernel.
|
||||
|
||||
---
|
||||
|
||||
#### Constructors and properties
|
||||
|
||||
* `g = GaussianKernel(bw=1.0)`
|
||||
- Create a `GaussianKernel` with the given bandwidth `bw`.
|
||||
|
||||
* `g.Bandwidth()` returns the bandwidth of the kernel as a `double`.
|
||||
- To set the bandwidth, use `g.Bandwidth(newBandwidth)`.
|
||||
|
||||
---
|
||||
|
||||
#### Kernel evaluation
|
||||
|
||||
* `g.Evaluate(x1, x2)`
|
||||
- Compute the kernel value between two vectors `x1` and `x2`.
|
||||
- `x1` and `x2` should be vector types that implement the Armadillo API
|
||||
@@ -423,6 +540,10 @@ where `bw` is the bandwidth parameter of the kernel.
|
||||
between those two vectors (`distance`) is already known.
|
||||
- `distance` should have type `double`.
|
||||
|
||||
---
|
||||
|
||||
#### Other utilities
|
||||
|
||||
* `g.Gradient(distance)`
|
||||
- Compute the (one-dimensional) gradient of the kernel function with respect
|
||||
to the distance between two points, evaluated at `distance`.
|
||||
@@ -438,16 +559,18 @@ where `bw` is the bandwidth parameter of the kernel.
|
||||
|
||||
```c++
|
||||
// Create a Gaussian kernel with default bandwidth.
|
||||
GaussianKernel g;
|
||||
mlpack::GaussianKernel g;
|
||||
|
||||
// Create a Gaussian kernel with bandwidth 5.0.
|
||||
GaussianKernel g2(5.0);
|
||||
mlpack::GaussianKernel g2(5.0);
|
||||
|
||||
// Evaluate the kernel value between two 3-dimensional points.
|
||||
arma::vec x1("0.5 1.0 1.5");
|
||||
arma::vec x2("1.5 1.0 0.5");
|
||||
const double k1 = g.Evaluate(x1, x2);
|
||||
const double k2 = g2.Evaluate(x1, x2);
|
||||
std::cout << "Kernel values: " << k1 << " (bw=1.0), " << k2 << " (bw=5.0)."
|
||||
<< std::endl;
|
||||
|
||||
// Evaluate the kernel value when the distance between two points is already
|
||||
// computed.
|
||||
@@ -457,16 +580,19 @@ const double k3 = g.Evaluate(distance);
|
||||
// Change the bandwidth of the kernel to 2.5.
|
||||
g.Bandwidth(2.5);
|
||||
const double k4 = g.Evaluate(x1, x2);
|
||||
std::cout << "Kernel value with bw=2.5: " << k4 << "." << std::endl;
|
||||
|
||||
// Evaluate the kernel value between x1 and all points in a random matrix.
|
||||
arma::mat r(3, 100, arma::fill::randu);
|
||||
arma::vec kernelValues(100);
|
||||
for (size_t i = 0; i < r.n_cols; ++i)
|
||||
kernelValues[i] = g.Evaluate(x1, r.col(i));
|
||||
std::cout << "Average kernel value for random points: "
|
||||
<< arma::mean(kernelValues) << "." << std::endl;
|
||||
|
||||
// Compute the kernel value between two 32-bit floating-point vectors.
|
||||
arma::fvec fx1("0.5 1.0 1.5");
|
||||
arma::fvec fx2("1.5 1.0 0.5");
|
||||
const double k4 = g.Evaluate(fx1, fx2);
|
||||
const double k5 = g2.Evaluate(fx1, fx2);
|
||||
const double k5 = g.Evaluate(fx1, fx2);
|
||||
const double k6 = g2.Evaluate(fx1, fx2);
|
||||
```
|
||||
|
||||
+242
-139
@@ -6,26 +6,41 @@ any mlpack object via the [cereal](https://uscilab.github.io/cereal/)
|
||||
serialization toolkit. A number of other utilities related to loading and
|
||||
saving data and objects are also available.
|
||||
|
||||
* [Numeric data](#numeric-data)
|
||||
* [Mixed categorical data](#mixed-categorical-data)
|
||||
- [`data::DatasetInfo`](#datadatasetinfo)
|
||||
- [Loading categorical data](#loading-categorical-data)
|
||||
* [Image data](#image-data)
|
||||
- [`data::ImageInfo`](#dataimageinfo)
|
||||
- [Loading images](#loading-images)
|
||||
* [mlpack objects](#mlpack-objects): load or save any mlpack object
|
||||
* [Normalizing labels](#normalizing-labels): convert labels to ranges required
|
||||
by mlpack classifiers
|
||||
* [Formats](#formats): supported formats for each load/save variant
|
||||
|
||||
## Numeric data
|
||||
|
||||
Numeric data or general numeric matrices can be loaded or saved with the
|
||||
following functions.
|
||||
|
||||
- `data::Load(filename, matrix, fatal=false, transpose=true,
|
||||
format=FileType::AutoDetect)`
|
||||
- `data::Save(filename, matrix, fatal=false, transpose=true,
|
||||
format=FileType::AutoDetect)`
|
||||
- `data::Load(filename, matrix, fatal=false, transpose=true, format=FileType::AutoDetect)`
|
||||
- `data::Save(filename, matrix, fatal=false, transpose=true, format=FileType::AutoDetect)`
|
||||
* `filename` is a `std::string` with a path to the file to be loaded.
|
||||
|
||||
* By default the format is auto-detected based on the file extension, but can
|
||||
be explicitly specified with `format`; see [Formats](#formats).
|
||||
|
||||
* `matrix` is an `arma::mat&`, `arma::Mat<size_t>&`, or similar (e.g., a
|
||||
reference to an Armadillo object that data will be loaded into or saved
|
||||
from).
|
||||
|
||||
* If `fatal` is `true`, a `std::runtime_error` will be thrown on failure.
|
||||
|
||||
* If `transpose` is `true`, then for plaintext formats (CSV/TSV/ASCII), the
|
||||
matrix will be transposed on save. (Keep this `true` if you want a
|
||||
column-major matrix to be saved with points as rows and dimensions as
|
||||
columns; that is generally what is desired.)
|
||||
|
||||
* A `bool` is returned indicating whether the operation was successful.
|
||||
|
||||
---
|
||||
@@ -48,8 +63,8 @@ std::cout << " - " << dataset.n_rows << " dimensions." << std::endl;
|
||||
|
||||
std::cout << "The labels in 'satellite.train.labels.csv' have: " << std::endl;
|
||||
std::cout << " - " << labels.n_elem << " labels." << std::endl;
|
||||
std::cout << " - A maximum label of " << labels.max() << std::endl;
|
||||
std::cout << " - A minimum label of " << labels.min() << std::endl;
|
||||
std::cout << " - A maximum label of " << labels.max() << "." << std::endl;
|
||||
std::cout << " - A minimum label of " << labels.min() << "." << std::endl;
|
||||
|
||||
// Modify and save the data. Add 2 to the data and drop the last column.
|
||||
dataset += 2;
|
||||
@@ -70,7 +85,7 @@ mlpack, string data and other non-numerical data must be mapped to categorical
|
||||
values and represented as part of an `arma::mat`. Category information is
|
||||
stored in an auxiliary `data::DatasetInfo` object.
|
||||
|
||||
### `DatasetInfo`
|
||||
### `data::DatasetInfo`
|
||||
|
||||
<!-- TODO: also document in core.md? -->
|
||||
|
||||
@@ -79,15 +94,23 @@ mlpack represents categorical data via the use of the auxiliary
|
||||
numeric or categorical and allows conversion from the original category values
|
||||
to the numeric values used to represent those categories.
|
||||
|
||||
---
|
||||
|
||||
#### Constructors
|
||||
|
||||
- `info = data::DatasetInfo()`
|
||||
* Create an empty `DatasetInfo` object.
|
||||
* Use this constructor if you intend to populate the `DatasetInfo` via a
|
||||
`data::Load()` call.
|
||||
* Create an empty `data::DatasetInfo` object.
|
||||
* Use this constructor if you intend to populate the `data::DatasetInfo` via
|
||||
a `data::Load()` call.
|
||||
|
||||
- `info = data::DatasetInfo(dimensionality)`
|
||||
* Create a `DatasetInfo` object with the given dimensionality
|
||||
* Create a `data::DatasetInfo` object with the given dimensionality
|
||||
* All dimensions are assumed to be numeric (not categorical).
|
||||
|
||||
---
|
||||
|
||||
#### Accessing and setting properties
|
||||
|
||||
- `info.Type(d)`
|
||||
* Get the type (categorical or numeric) of dimension `d`.
|
||||
* Returns a `data::Datatype`, either `data::Datatype::numeric` or
|
||||
@@ -103,9 +126,13 @@ to the numeric values used to represent those categories.
|
||||
- `info.Dimensionality()`
|
||||
* Return the dimensionality of the object as a `size_t`.
|
||||
|
||||
- `info.MapString(value, d)`
|
||||
* Given `value` (a `std::string`), return the `size_t` representing the
|
||||
categorical mapping of `value` in dimension `d`.
|
||||
---
|
||||
|
||||
#### Map to and from numeric values
|
||||
|
||||
- `info.MapString<double>(value, d)`
|
||||
* Given `value` (a `std::string`), return the `double` representing the
|
||||
categorical mapping (an integer value) of `value` in dimension `d`.
|
||||
* If a mapping for `value` does not exist in dimension `d`, a new mapping is
|
||||
created, and `info.NumMappings(d)` is increased by one.
|
||||
* If dimension `d` is numeric and `value` cannot be parsed as a numeric
|
||||
@@ -119,10 +146,13 @@ to the numeric values used to represent those categories.
|
||||
|
||||
---
|
||||
|
||||
With a `DatasetInfo` object, categorical data can be loaded:
|
||||
### Loading categorical data
|
||||
|
||||
With a `data::DatasetInfo` object, categorical data can be loaded:
|
||||
|
||||
- `data::Load(filename, matrix, info, fatal=false, transpose=true)`
|
||||
* `filename` is a `std::string` with a path to the file to be loaded.
|
||||
|
||||
* The format is auto-detected based on the extension of the filename and the
|
||||
contents of the file:
|
||||
- `.csv`, `.tsv`, or `.txt` for CSV/TSV (tab-separated)/ASCII
|
||||
@@ -132,14 +162,18 @@ With a `DatasetInfo` object, categorical data can be loaded:
|
||||
* `matrix` is an `arma::mat&`, `arma::Mat<size_t>&`, or similar (e.g., a
|
||||
reference to an Armadillo object that data will be loaded into or saved
|
||||
from).
|
||||
|
||||
* `info` is a `data::DatasetInfo&` object. This will be populated with the
|
||||
category information of the file when loading, and used to unmap values
|
||||
when saving.
|
||||
|
||||
* If `fatal` is `true`, a `std::runtime_error` will be thrown on failure.
|
||||
|
||||
* If `transpose` is `true`, then for plaintext formats (CSV/TSV/ASCII), the
|
||||
matrix will be transposed on save. (Keep this `true` if you want a
|
||||
column-major matrix to be saved with points as rows and dimensions as
|
||||
columns; that is generally what is desired.)
|
||||
|
||||
* A `bool` is returned indicating whether the operation was successful.
|
||||
|
||||
Saving should be performed with the [numeric](#numeric-data) `data::Load()`
|
||||
@@ -187,7 +221,7 @@ for (size_t d = 0; d < info.Dimensionality(); ++d)
|
||||
{
|
||||
// This will create a new mapping if the string "hooray!" does not already
|
||||
// exist as a category for dimension d..
|
||||
dataset(d, 4) = info.MapString("hooray!", d);
|
||||
dataset(d, 4) = info.MapString<double>("hooray!", d);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -198,7 +232,7 @@ for (size_t d = 0; d < info.Dimensionality(); ++d)
|
||||
|
||||
---
|
||||
|
||||
Example usage to manually create a `DatasetInfo` object.
|
||||
Example usage to manually create a `data::DatasetInfo` object.
|
||||
|
||||
```c++
|
||||
// This will manually create the following data matrix (shown as it would appear
|
||||
@@ -232,20 +266,20 @@ dataset(0, 4) = 5;
|
||||
dataset(0, 5) = 6;
|
||||
|
||||
// The second dimension is categorical.
|
||||
dataset(1, 0) = info.MapString("TRUE", 1);
|
||||
dataset(1, 1) = info.MapString("FALSE", 1);
|
||||
dataset(1, 2) = info.MapString("FALSE", 1);
|
||||
dataset(1, 3) = info.MapString("TRUE", 1);
|
||||
dataset(1, 4) = info.MapString("TRUE", 1);
|
||||
dataset(1, 5) = info.MapString("FALSE", 1);
|
||||
dataset(1, 0) = info.MapString<double>("TRUE", 1);
|
||||
dataset(1, 1) = info.MapString<double>("FALSE", 1);
|
||||
dataset(1, 2) = info.MapString<double>("FALSE", 1);
|
||||
dataset(1, 3) = info.MapString<double>("TRUE", 1);
|
||||
dataset(1, 4) = info.MapString<double>("TRUE", 1);
|
||||
dataset(1, 5) = info.MapString<double>("FALSE", 1);
|
||||
|
||||
// The third dimension is categorical.
|
||||
dataset(2, 0) = info.MapString("good", 2);
|
||||
dataset(2, 1) = info.MapString("good", 2);
|
||||
dataset(2, 2) = info.MapString("bad", 2);
|
||||
dataset(2, 3) = info.MapString("bad", 2);
|
||||
dataset(2, 4) = info.MapString("unknown", 2);
|
||||
dataset(2, 5) = info.MapString("unknown", 2);
|
||||
dataset(2, 0) = info.MapString<double>("good", 2);
|
||||
dataset(2, 1) = info.MapString<double>("good", 2);
|
||||
dataset(2, 2) = info.MapString<double>("bad", 2);
|
||||
dataset(2, 3) = info.MapString<double>("bad", 2);
|
||||
dataset(2, 4) = info.MapString<double>("unknown", 2);
|
||||
dataset(2, 5) = info.MapString<double>("unknown", 2);
|
||||
|
||||
// The fourth dimension is numeric.
|
||||
dataset(3, 0) = 7.0;
|
||||
@@ -259,12 +293,12 @@ dataset(3, 5) = 5.1;
|
||||
// category values in the order they are seen, even if the category can be
|
||||
// parsed as a number. So, here, the value '4' will be assigned category '0',
|
||||
// since it is seen first.
|
||||
dataset(4, 0) = info.MapString("4", 4);
|
||||
dataset(4, 1) = info.MapString("3", 4);
|
||||
dataset(4, 2) = info.MapString("4", 4);
|
||||
dataset(4, 3) = info.MapString("1", 4);
|
||||
dataset(4, 4) = info.MapString("0", 4);
|
||||
dataset(4, 5) = info.MapString("2", 4);
|
||||
dataset(4, 0) = info.MapString<double>("4", 4);
|
||||
dataset(4, 1) = info.MapString<double>("3", 4);
|
||||
dataset(4, 2) = info.MapString<double>("4", 4);
|
||||
dataset(4, 3) = info.MapString<double>("1", 4);
|
||||
dataset(4, 4) = info.MapString<double>("0", 4);
|
||||
dataset(4, 5) = info.MapString<double>("2", 4);
|
||||
|
||||
// Print the dataset with mapped categories.
|
||||
dataset.print("Dataset with mapped categories");
|
||||
@@ -277,10 +311,8 @@ for (size_t i = 0; i < info.NumMappings(2); ++i)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
|
||||
// Save as a CSV. Note that this will look the same as the comment at the start
|
||||
// of this example!
|
||||
mlpack::data::Save("manual_categorical_data.csv", dataset, info);
|
||||
// Now `dataset` is ready for use with an mlpack algorithm that supports
|
||||
// categorical data.
|
||||
```
|
||||
|
||||
---
|
||||
@@ -298,31 +330,39 @@ Supported formats for saving are `jpg`, `png`, `tga`, `bmp`, and `hdr`.
|
||||
|
||||
When loading images, each image is represented as a flattened single column
|
||||
vector in a data matrix; each row of the resulting vector will correspond to a
|
||||
single pixel value in a single channel. An auxiliary `ImageInfo` class is used
|
||||
to store information about the images.
|
||||
single pixel value in a single channel. An auxiliary `data::ImageInfo` class is
|
||||
used to store information about the images.
|
||||
|
||||
### `ImageInfo`
|
||||
### `data::ImageInfo`
|
||||
|
||||
The `ImageInfo` class contains the metadata of the images.
|
||||
The `data::ImageInfo` class contains the metadata of the images.
|
||||
|
||||
- `info = ImageInfo()`
|
||||
* Create an `ImageInfo` object with no data.
|
||||
* Use this constructor if you intend to populate the `DatasetInfo` via a
|
||||
---
|
||||
|
||||
#### Constructors
|
||||
|
||||
- `info = data::ImageInfo()`
|
||||
* Create a `data::ImageInfo` object with no data.
|
||||
* Use this constructor if you intend to populate the `data::ImageInfo` via a
|
||||
`data::Load()` call.
|
||||
|
||||
- `info = ImageInfo(width, height, channels)`
|
||||
* Create an `ImageInfo` object with the given image specifications.
|
||||
- `info = data::ImageInfo(width, height, channels)`
|
||||
* Create a `data::ImageInfo` object with the given image specifications.
|
||||
* `width` and `height` are specified as pixels.
|
||||
|
||||
- `info.Quality(q)` will set the compression quality (e.g. for saving JPEGs) to
|
||||
`q`.
|
||||
---
|
||||
|
||||
#### Accessing and modifying image metadata
|
||||
|
||||
- `info.Quality() = q` will set the compression quality (e.g. for saving JPEGs)
|
||||
to `q`.
|
||||
* `q` should take values between `0` and `100`.
|
||||
* The quality value is ignored unless calling `data::Save()` with `info`.
|
||||
|
||||
- Calling `info.Channels(1)` before loading will cause images to be loaded in
|
||||
grayscale.
|
||||
- Calling `info.Channels() = 1` before loading will cause images to be loaded
|
||||
in grayscale.
|
||||
|
||||
- Metadata stored in the `ImageInfo()` can be accessed with the following
|
||||
- Metadata stored in the `data::ImageInfo` can be accessed with the following
|
||||
members:
|
||||
* `info.Width()` returns the image width in pixels.
|
||||
* `info.Height()` returns the image height in pixels.
|
||||
@@ -332,53 +372,76 @@ The `ImageInfo` class contains the metadata of the images.
|
||||
|
||||
---
|
||||
|
||||
With an `ImageInfo` object, image data can be loaded or saved, handling either
|
||||
one or multiple images at a time:
|
||||
### Loading images
|
||||
|
||||
With a `data::ImageInfo` object, image data can be loaded or saved, handling
|
||||
either one or multiple images at a time:
|
||||
|
||||
<!-- TODO: add parameter to force use of what's in `info` -->
|
||||
|
||||
- `data::Load(filename, matrix, info, fatal=false)`
|
||||
* Load a *single image* from `filename` into `matrix`.
|
||||
* Format is chosen by extension (e.g. `image.png` will load as PNG).
|
||||
* Load a ***single image*** from `filename` into `matrix`.
|
||||
- Format is chosen by extension (e.g. `image.png` will load as PNG).
|
||||
|
||||
* `matrix` will have one column representing the image as a flattened vector.
|
||||
|
||||
* `info` will be populated with information from the image in `filename`.
|
||||
|
||||
* If `fatal` is `true`, a `std::runtime_error` will be thrown upon load
|
||||
failure.
|
||||
|
||||
* Returns a `bool` indicating the success of the operation.
|
||||
|
||||
---
|
||||
|
||||
- `data::Load(files, matrix, info, fatal=false)`
|
||||
* Load *multiple images* from `files` into `matrix`.
|
||||
* `files` is of type `std::vector<std::string>` and should contain the list
|
||||
of images to be loaded.
|
||||
* `matrix` will have `files.size()` columns, each representing the
|
||||
corresponding image as a flattened vector.
|
||||
* Load ***multiple images*** from `files` into `matrix`.
|
||||
- `files` is of type `std::vector<std::string>` and should contain the list
|
||||
of images to be loaded.
|
||||
- `matrix` will have `files.size()` columns, each representing the
|
||||
corresponding image as a flattened vector.
|
||||
|
||||
* `info` will be populated with information from the images in `files`.
|
||||
|
||||
* If `fatal` is `true`, a `std::runtime_error` will be thrown if any files
|
||||
fail to load.
|
||||
|
||||
* Returns a `bool` indicating the success of the operation.
|
||||
|
||||
---
|
||||
|
||||
- `data::Save(filename, matrix, info, fatal=false)`
|
||||
* Save a *single image* from `matrix` into the file `filename`.
|
||||
* Format is chosen by extension (e.g. `image.png` will save as PNG).
|
||||
* Save a ***single image*** from `matrix` into the file `filename`.
|
||||
- Format is chosen by extension (e.g. `image.png` will save as PNG).
|
||||
|
||||
* `matrix` is expected to have only one column representing the image as a
|
||||
flattened vector.
|
||||
|
||||
* If `fatal` is `true`, a `std::runtime_error` will be thrown in the event of
|
||||
save failure.
|
||||
|
||||
* Returns a `bool` indicating the success of the operation.
|
||||
|
||||
---
|
||||
|
||||
- `data::Save(files, matrix, info, fatal=false)`
|
||||
* Save *multiple images* from `matrix` into `files`.
|
||||
* `files` is of type `std::vector<std::string>` and should contain the list
|
||||
of files to save to.
|
||||
* The format of each file is chosen by extension (e.g. `image.png` will save
|
||||
as PNG); it is allowed for filenames in `files` to have different
|
||||
extensions.
|
||||
* Save ***multiple images*** from `matrix` into `files`.
|
||||
- `files` is of type `std::vector<std::string>` and should contain the list
|
||||
of files to save to.
|
||||
- The format of each file is chosen by extension (e.g. `image.png` will
|
||||
save as PNG); it is allowed for filenames in `files` to have different
|
||||
extensions.
|
||||
|
||||
* `matrix` is expected to have `files.size()` columns representing images as
|
||||
flattened vectors.
|
||||
|
||||
* If `fatal` is `true`, a `std::runtime_error` will be thrown if any images
|
||||
fail to save.
|
||||
|
||||
* Returns a `bool` indicating the success of the operation.
|
||||
|
||||
---
|
||||
|
||||
Images are flattened along rows, with channel values interleaved, starting from
|
||||
the top left. Thus, the value of the pixel at position `(x, y)` in channel `c`
|
||||
will be contained in element/row `y * (width * channels) + x * (channels) + c`
|
||||
@@ -412,7 +475,7 @@ std::cout << matrix[index] << "." << std::endl;
|
||||
|
||||
// Increment each pixel value, but make sure they are still within the bounds.
|
||||
matrix += 1;
|
||||
matrix.clamp(0, 255);
|
||||
matrix = arma::clamp(matrix, 0, 255);
|
||||
|
||||
mlpack::data::Save("numfocus-logo-mod.png", matrix, info);
|
||||
```
|
||||
@@ -434,7 +497,7 @@ images.push_back("ensmallen-favicon.png");
|
||||
images.push_back("armadillo-favicon.png");
|
||||
images.push_back("bandicoot-favicon.png");
|
||||
|
||||
ImageInfo info;
|
||||
mlpack::data::ImageInfo info;
|
||||
info.Channels(1); // Force loading in grayscale.
|
||||
|
||||
arma::mat matrix;
|
||||
@@ -449,7 +512,7 @@ std::cout << "Loaded " << matrix.n_cols << " images. Images are of size "
|
||||
matrix = (255.0 - matrix);
|
||||
|
||||
// Save as compressed JPEGs with low quality.
|
||||
info.Quality(75);
|
||||
info.Quality() = 75;
|
||||
std::vector<std::string> outImages;
|
||||
outImages.push_back("mlpack-favicon-inv.jpeg");
|
||||
outImages.push_back("ensmallen-favicon-inv.jpeg");
|
||||
@@ -469,21 +532,25 @@ Each object must be given a logical name.
|
||||
- `data::Load(filename, name, object, fatal=false, format=data::format::autodetect)`
|
||||
- `data::Save(filename, name, object, fatal=false, format=data::format::autodetect)`
|
||||
* Load/save `object` to/from `filename` with the logical name `name`.
|
||||
|
||||
* If `fatal` is `true`, a `std::runtime_error` will be thrown in the event of
|
||||
load or save failure.
|
||||
|
||||
* The format is autodetected based on extension (`.bin`, `.json`, or `.xml`),
|
||||
but can be manually specified:
|
||||
- `data::format::binary`: binary blob (smallest and fastest). No checks;
|
||||
assumes all data is correct.
|
||||
- `data::format::json`: JSON.
|
||||
- `data::format::xml`: XML (largest and slowest).
|
||||
|
||||
* For JSON and XML types, when loading, `name` must match the name used to
|
||||
save the object.
|
||||
|
||||
* Returns a `bool` indicating the success of the operation.
|
||||
|
||||
***Note:*** when loading an object that was saved as a binary blob, the C++ type
|
||||
of the object must be *exactly the same* (including template parameters) as the
|
||||
type used to save the object. If not, undefined behavior will occur---most
|
||||
of the object must be ***exactly the same*** (including template parameters) as
|
||||
the type used to save the object. If not, undefined behavior will occur---most
|
||||
likely a crash.
|
||||
|
||||
---
|
||||
@@ -526,19 +593,26 @@ mlpack classifiers and other algorithms require labels to be in the range `0` to
|
||||
`numClasses - 1`. A vector of labels with arbitrary (`size_t`) values can be
|
||||
normalized to the required range with the `NormalizeLabels()` function.
|
||||
|
||||
* `NormalizeLabels(labelsIn, labelsOut, mappings)`
|
||||
---
|
||||
|
||||
* `data::NormalizeLabels(labelsIn, labelsOut, mappings)`
|
||||
- Map vector `labelsIn` into the range `0` to `numClasses - 1`, storing as
|
||||
`labelsOut` (of type `arma::Row<size_t>`).
|
||||
- `numClasses` is automatically detected using the number of unique values
|
||||
in `labelsIn`.
|
||||
* `numClasses` is automatically detected using the number of unique values
|
||||
in `labelsIn`.
|
||||
|
||||
- The column vector `mappings` will be filled with the reverse mappings to
|
||||
convert back to the old labels; this can be used by `RevertLabels()`.
|
||||
|
||||
- `mappings[i]` contains the original class label for the mapped label `i`.
|
||||
|
||||
* `RevertLabels(labelsIn, mappings, labelsOut)`
|
||||
---
|
||||
|
||||
* `data::RevertLabels(labelsIn, mappings, labelsOut)`
|
||||
- Unmap normalized labels `labelsIn` using `mappings` into `labelsOut`.
|
||||
- Performs the reverse operation of `NormalizeLabels()`.
|
||||
- `mappings` should be the same vector output by `NormalizeLabels()`.
|
||||
|
||||
- Performs the reverse operation of `NormalizeLabels()`; `mappings` should
|
||||
be the same vector output by `NormalizeLabels()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -557,18 +631,18 @@ arma::Row<size_t> labels = { 3, 7, 3, 3, 5 };
|
||||
// We will map them to that range using NormalizeLabels().
|
||||
arma::Row<size_t> mappedLabels;
|
||||
arma::Col<size_t> mappings;
|
||||
NormalizeLabels(labels, mappedLabels, mapping);
|
||||
mlpack::data::NormalizeLabels(labels, mappedLabels, mappings);
|
||||
const size_t numClasses = mappedLabels.max() + 1;
|
||||
|
||||
// Print the mapped values:
|
||||
// [3, 7, 3, 3, 5] maps to [0, 1, 0, 0, 2].
|
||||
// The `mappings` vector will be [3, 7, 5].
|
||||
std::cout << "Original labels: " << labels;
|
||||
std::cout << "Mapped labels: " << mappedLabels;
|
||||
std::cout << "Mapped labels: " << mappedLabels;
|
||||
std::cout << "Mappings: " << mappings;
|
||||
|
||||
// Learn a model with the mapped labels.
|
||||
DecisionTree d(dataset, mappedLabels, numClasses);
|
||||
mlpack::DecisionTree d(dataset, mappedLabels, numClasses, 1 /* leaf size */);
|
||||
|
||||
// Make predictions on the training dataset.
|
||||
arma::Row<size_t> mappedPredictions;
|
||||
@@ -577,13 +651,13 @@ d.Classify(dataset, mappedPredictions);
|
||||
// The predictions use mapped labels (0, 1, 2), which we will need to map back
|
||||
// to the original labels using RevertLabels().
|
||||
arma::Row<size_t> predictions;
|
||||
RevertLabels(mappedPredictions, mappings, predictions);
|
||||
mlpack::data::RevertLabels(mappedPredictions, mappings, predictions);
|
||||
|
||||
// Print the predictions before and after unmapping.
|
||||
// The mapped predictions will take values 0, 1, or 2; the predictions will take
|
||||
// values 3, 7, or 5 (like the original data).
|
||||
std::cout << "Mapped predictions: " << mappedPredictions;
|
||||
std::cout << "Predictions: " << predictions;
|
||||
std::cout << "Predictions: " << predictions;
|
||||
```
|
||||
|
||||
## Formats
|
||||
@@ -591,34 +665,49 @@ std::cout << "Predictions: " << predictions;
|
||||
mlpack's `data::Load()` and `data::Save()` functions support a variety of
|
||||
different formats in different contexts.
|
||||
|
||||
* [Numeric data](#numeric-data)
|
||||
- By default, load/save format is autodetected, but can be manually specified
|
||||
with the `format` parameter using one of the options below:
|
||||
* `FileType::AutoDetect` (default): auto-detects the format as one of the
|
||||
formats below using the extension of the filename and inspecting the file
|
||||
contents.
|
||||
* `FileType::CSVASCII` (autodetect extensions `.csv`, `.tsv`): CSV format
|
||||
with no header.
|
||||
* `FileType::RawASCII` (autodetect extensions `.csv`, `.txt`):
|
||||
space-separated values or tab-separated values (TSV) with no header.
|
||||
* `FileType::ArmaASCII` (autodetect extension `.txt`): space-separated
|
||||
values as saved by Armadillo with the
|
||||
[`arma_ascii`](https://arma.sourceforge.net/docs.html#save_load_mat)
|
||||
format.
|
||||
* `FileType::CoordASCII` (not autodetected, must be manually specified):
|
||||
coordinate list format for sparse data (see
|
||||
[`coord_ascii`](https://arma.sourceforge.net/docs.html#save_load_mat)).
|
||||
* `FileType::ArmaBinary` (autodetect extension `.bin`): Armadillo's
|
||||
efficient binary matrix format
|
||||
([`arma_binary`](https://arma.sourceforge.net/docs.html#save_load_mat)).
|
||||
* `FileType::HDF5Binary` (autodetect extensions `.h5`, `.hdf5`, `.hdf`,
|
||||
`.he5`): [HDF5](https://en.wikipedia.org/wiki/Hierarchical_Data_Format)
|
||||
binary format; only available if Armadillo is configured with
|
||||
[HDF5 support](https://arma.sourceforge.net/docs.html#config_hpp).
|
||||
* `FileType::RawBinary` (autodetect extension `.bin`): packed binary data
|
||||
with no header and no size information; data will be loaded as a single
|
||||
column vector _(not recommended)_.
|
||||
* `FileType::PGMBinary` (autodetect extension `.pgm`): PGM image format
|
||||
---
|
||||
|
||||
#### [Numeric data](#numeric-data)
|
||||
|
||||
By default, load/save format is ***autodetected***, but can be manually
|
||||
specified with the `format` parameter using one of the options below:
|
||||
|
||||
- `FileType::AutoDetect` (default): auto-detects the format as one of the
|
||||
formats below using the extension of the filename and inspecting the file
|
||||
contents.
|
||||
|
||||
- `FileType::CSVASCII` (autodetect extensions `.csv`, `.tsv`): CSV format
|
||||
with no header.
|
||||
|
||||
- `FileType::RawASCII` (autodetect extensions `.csv`, `.txt`):
|
||||
space-separated values or tab-separated values (TSV) with no header.
|
||||
|
||||
- `FileType::ArmaASCII` (autodetect extension `.txt`): space-separated
|
||||
values as saved by Armadillo with the
|
||||
[`arma_ascii`](https://arma.sourceforge.net/docs.html#save_load_mat)
|
||||
format.
|
||||
|
||||
- `FileType::CoordASCII` (not autodetected, must be manually specified):
|
||||
coordinate list format for sparse data (see
|
||||
[`coord_ascii`](https://arma.sourceforge.net/docs.html#save_load_mat)).
|
||||
|
||||
- `FileType::ArmaBinary` (autodetect extension `.bin`): Armadillo's
|
||||
efficient binary matrix format
|
||||
([`arma_binary`](https://arma.sourceforge.net/docs.html#save_load_mat)).
|
||||
|
||||
- `FileType::HDF5Binary` (autodetect extensions `.h5`, `.hdf5`, `.hdf`,
|
||||
`.he5`): [HDF5](https://en.wikipedia.org/wiki/Hierarchical_Data_Format)
|
||||
binary format; only available if Armadillo is configured with
|
||||
[HDF5 support](https://arma.sourceforge.net/docs.html#config_hpp).
|
||||
|
||||
- `FileType::RawBinary` (autodetect extension `.bin`): packed binary data
|
||||
with no header and no size information; data will be loaded as a single
|
||||
column vector _(not recommended)_.
|
||||
|
||||
- `FileType::PGMBinary` (autodetect extension `.pgm`): PGM image format
|
||||
|
||||
***Notes:***
|
||||
|
||||
- ASCII formats (`CSVASCII`, `RawASCII`, `ArmaASCII`) are human-readable but
|
||||
large; to reduce dataset size, consider a binary format such as
|
||||
`ArmaBinary` or `HDF5Binary`.
|
||||
@@ -626,30 +715,44 @@ different formats in different contexts.
|
||||
binary format (`ArmaBinary` or `HDF5Binary`) or as a coordinate list
|
||||
(`CoordASCII`).
|
||||
|
||||
* [Mixed categorical data](#mixed-categorical-data)
|
||||
- The format of mixed categorical data is detected automatically based on the
|
||||
file extension and inspecting the file contents:
|
||||
* `.csv`, `.txt`, or `.tsv` indicates CSV/TSV/ASCII format
|
||||
* `.arff` indicates [ARFF](https://www.cs.waikato.ac.nz/~ml/weka/arff.html)
|
||||
---
|
||||
|
||||
* [Image data](#image-data)
|
||||
- The format of images are detected automatically based on the file
|
||||
extension.
|
||||
- The following formats are supported for loading: `.jpg`, `.jpeg`, `.png`,
|
||||
`.tga`, `.bmp`, `.psd`, `.gif`, `.hdr`, `.pic`, `.pnm`
|
||||
- The following formats are supported for saving: `.jpg`, `.png`, `.tga`,
|
||||
`.bmp`, `.hdr`
|
||||
#### [Mixed categorical data](#mixed-categorical-data)
|
||||
|
||||
* [mlpack objects](#mlpack-objects)
|
||||
- By default, load/save format for mlpack objects is autodetected, but can be
|
||||
manually specified with the `format` parameter using one of the options
|
||||
below:
|
||||
* `format::autodetect` (default): auto-detects the format as one of the
|
||||
formats below using the extension of the filename
|
||||
* `format::json` (autodetect extension `.json`)
|
||||
* `format::xml` (autodetect extension `.xml`)
|
||||
* `format::binary` (autodetect extension `.bin`)
|
||||
- `format::json` (`.json`) and `format::xml` (`.xml`) produce human-readable
|
||||
files, but they may be quite large.
|
||||
- `format::binary` (`.bin`) is recommended for the sake of size; objects in
|
||||
binary format may be an order of magnitude or more smaller than JSON!
|
||||
The format of mixed categorical data is detected automatically based on the
|
||||
file extension and inspecting the file contents:
|
||||
|
||||
- `.csv`, `.txt`, or `.tsv` indicates CSV/TSV/ASCII format
|
||||
- `.arff` indicates [ARFF](https://www.cs.waikato.ac.nz/~ml/weka/arff.html)
|
||||
|
||||
---
|
||||
|
||||
#### [Image data](#image-data)
|
||||
|
||||
The format of images are detected automatically based on the file extension.
|
||||
|
||||
- The following formats are supported for loading: `.jpg`, `.jpeg`, `.png`,
|
||||
`.tga`, `.bmp`, `.psd`, `.gif`, `.hdr`, `.pic`, `.pnm`
|
||||
|
||||
- The following formats are supported for saving: `.jpg`, `.png`, `.tga`,
|
||||
`.bmp`, `.hdr`
|
||||
|
||||
---
|
||||
|
||||
#### [mlpack objects](#mlpack-objects)
|
||||
|
||||
By default, load/save format for mlpack objects is autodetected, but can be
|
||||
manually specified with the `format` parameter using one of the options below:
|
||||
|
||||
- `format::autodetect` (default): auto-detects the format as one of the
|
||||
formats below using the extension of the filename
|
||||
- `format::json` (autodetect extension `.json`)
|
||||
- `format::xml` (autodetect extension `.xml`)
|
||||
- `format::binary` (autodetect extension `.bin`)
|
||||
|
||||
***Notes:***
|
||||
|
||||
- `format::json` (`.json`) and `format::xml` (`.xml`) produce human-readable
|
||||
files, but they may be quite large.
|
||||
- `format::binary` (`.bin`) is recommended for the sake of size; objects in
|
||||
binary format may be an order of magnitude or more smaller than JSON!
|
||||
|
||||
+40
-37
@@ -1,14 +1,23 @@
|
||||
# Matrices in mlpack
|
||||
|
||||
mlpack uses Armadillo matrices for matrix support. Armadillo is a fast C++
|
||||
matrix library which makes use of advanced template metaprogramming techniques
|
||||
to provide the fastest possible linear algebra operations.
|
||||
mlpack uses Armadillo matrices for linear algebra support. Armadillo is a fast
|
||||
C++ matrix library which uses advanced template metaprogramming techniques to
|
||||
provide the fastest possible linear algebra operations.
|
||||
|
||||
Documentation on Armadillo can be found on [the Armadillo
|
||||
<center><p><img src="https://arma.sourceforge.net/img/armadillo_logo2.png" alt="Armadillo logo"></p></center>
|
||||
|
||||
Detailed documentation on Armadillo can be found on [the Armadillo
|
||||
website](http://arma.sourceforge.net/docs.html).
|
||||
|
||||
Nonetheless, there are a few further caveats for mlpack Armadillo usage.
|
||||
|
||||
* [An Armadillo primer](#an-armadillo-primer)
|
||||
* [Representing data in mlpack](#representing-data-in-mlpack)
|
||||
* [Loading data](#loading-data)
|
||||
* [Loading and using categorical data](#loading-and-using-categorical-data)
|
||||
* [Alternate matrix types](#alternate-matrix-types)
|
||||
* [Adapting from other toolkits (Eigen, etc.)](#adapting-from-other-toolkits-eigen-etc)
|
||||
|
||||
## An Armadillo primer
|
||||
|
||||
The Armadillo syntax is straightforward and is aimed at ease-of-use and
|
||||
@@ -20,15 +29,15 @@ matrix operations.
|
||||
// Create a 10x15 matrix with random elements.
|
||||
arma::mat m(10, 15, arma::fill::randu);
|
||||
|
||||
std::cout << "Size of m: " << x.n_rows << " x " << x.n_cols << "." << std::endl;
|
||||
std::cout << "Size of m: " << m.n_rows << " x " << m.n_cols << "." << std::endl;
|
||||
|
||||
// Sum all elements in the matrix.
|
||||
const double sumVal = arma::accu(m);
|
||||
std::cout << "Sum of all elements: " << sumVal << "." << std::endl;
|
||||
|
||||
// Sum the elements in each column.
|
||||
arma::vec sums = arma::sum(m, 0);
|
||||
std::cout << "Sums in each column: " << sums.t();
|
||||
arma::rowvec sums = arma::sum(m, 0);
|
||||
std::cout << "Sums in each column: " << sums;
|
||||
|
||||
// Add 1 to all elements.
|
||||
m += 1;
|
||||
@@ -50,16 +59,16 @@ For more information on Armadillo, see the following resources:
|
||||
|
||||
## Representing data in mlpack
|
||||
|
||||
Armadillo matrices, unlike numpy and some other toolkits, stores data in a
|
||||
*column-major* format. This means that each column is located in contiguous
|
||||
Armadillo matrices, unlike numpy and some other toolkits, store data in a
|
||||
***column-major*** format. This means that each column is located in contiguous
|
||||
memory; i.e., `x(0, 0)` is adjacent to `x(1, 0)` in memory.
|
||||
|
||||
This means that, for the vast majority of machine learning methods, it is faster
|
||||
to store _observations as columns_ and _dimensions as rows_. This is counter to
|
||||
most standard machine learning texts! It also has some implications for linear
|
||||
algebra operations; for instance, computing the Gram matrix of a matrix `X` is
|
||||
typically expressed as `X^T X`, but when using column-major matrices, the
|
||||
expression must be `X X^T`.
|
||||
to store ***observations as columns*** and ***dimensions as rows***. This is
|
||||
counter to most standard machine learning texts! It also has some implications
|
||||
for linear algebra operations; for instance, computing the Gram matrix of a
|
||||
matrix `X` is typically expressed as `X^T X`, but when using column-major
|
||||
matrices, the expression must be `X X^T`.
|
||||
|
||||
In general, the following Armadillo types are commonly used inside mlpack:
|
||||
|
||||
@@ -77,11 +86,8 @@ In general, the following Armadillo types are commonly used inside mlpack:
|
||||
mlpack provides two simple functions for loading and saving data matrices in a
|
||||
column-major form:
|
||||
|
||||
* `data::Load(filename, matrix, fatal=false, transpose=true,
|
||||
type=FileType::AutoDetect)` ([full documentation](load_save.md#numeric_data))
|
||||
|
||||
* `data::Save(filename, matrix, fatal=false, transpose=true,
|
||||
type=FileType::AutoDetect)` ([full documentation](load_save.md#numeric_data))
|
||||
* `data::Load(filename, matrix, fatal=false, transpose=true, type=FileType::AutoDetect)` ([full documentation](load_save.md#numeric_data))
|
||||
* `data::Save(filename, matrix, fatal=false, transpose=true, type=FileType::AutoDetect)` ([full documentation](load_save.md#numeric_data))
|
||||
|
||||
As an example, consider the following CSV file:
|
||||
|
||||
@@ -117,11 +123,11 @@ mlpack::data::Load("data.csv", m, true);
|
||||
// - each row corresponds to a dimension!
|
||||
//
|
||||
std::cout << "The matrix in 'data.csv' has: " << std::endl;
|
||||
std::cout << " - " << data.n_cols << " points." << std::endl;
|
||||
std::cout << " - " << data.n_rows << " dimensions." << std::endl;
|
||||
std::cout << " - " << m.n_cols << " points." << std::endl;
|
||||
std::cout << " - " << m.n_rows << " dimensions." << std::endl;
|
||||
|
||||
std::cout << "The second point in the dataset: " << std::endl;
|
||||
std::cout << data.col(1).t();
|
||||
std::cout << m.col(1).t();
|
||||
|
||||
// Now modify the matrix and save to a different format (space-separated
|
||||
// values).
|
||||
@@ -131,25 +137,21 @@ mlpack::data::Save("data-mod.txt", m);
|
||||
|
||||
Although Armadillo does provide a `.load()` and `.save()` member function for
|
||||
matrices, the `data::Load()` and `data::Save()` functions offer additional
|
||||
flexibility, and ensure that data is loaded in a column-major format.
|
||||
flexibility, and ensure that data is saved and loaded in a column-major format.
|
||||
|
||||
## Loading and using categorical data
|
||||
|
||||
Some mlpack techniques support mixed categorical data, e.g., data where some
|
||||
dimensions take only categorical values (e.g. `0`, `1`, `2`, etc.). String data
|
||||
and other non-numerical data can be represented as categorical values, and
|
||||
mlpack has support to load and save mixed categorical data:
|
||||
mlpack has support to load mixed categorical data:
|
||||
|
||||
* The `data::DatasetInfo` auxiliary class stores information about whether each
|
||||
dimension is numeric or categorical. ([full
|
||||
documentation](load_save.md#dataset_info))
|
||||
|
||||
* `data::Load(filename, matrix, info, fatal=false, transpose=true)` ([full
|
||||
documentation](load_save.md#load_categorical))
|
||||
|
||||
* `data::Save(filename, matrix, info, fatal=false, transpose=true)` ([full
|
||||
documentation](load_save.md#save_categorical))
|
||||
|
||||
For example, consider the following CSV file that contains strings:
|
||||
|
||||
```sh
|
||||
@@ -170,7 +172,8 @@ $ cat mixed_string_data.csv
|
||||
```
|
||||
|
||||
The following program will load the data file, print information about
|
||||
categorical dimensions, then save categorical data back to disk.
|
||||
categorical dimensions, and prepare the data for use with an mlpack algorithm
|
||||
that supports mixed categorical data.
|
||||
|
||||
```c++
|
||||
// Load data from `mixed_string_data.csv` into `m`. Throw an exception on
|
||||
@@ -181,7 +184,7 @@ mlpack::data::Load("mixed_string_data.csv", m, info, true);
|
||||
|
||||
// Print information about the data.
|
||||
std::cout << "The matrix in 'mixed_string_data.csv' has: " << std::endl;
|
||||
std::cout << " - " << data.n_cols << " points." << std::endl;
|
||||
std::cout << " - " << m.n_cols << " points." << std::endl;
|
||||
std::cout << " - " << info.Dimensionality() << " dimensions." << std::endl;
|
||||
|
||||
// Print which dimensions are categorical.
|
||||
@@ -198,14 +201,12 @@ for (size_t d = 0; d < info.Dimensionality(); ++d)
|
||||
// Note that we manually map the string values; MapString() returns the category
|
||||
// for a given value.
|
||||
m(0, 2) = 4;
|
||||
m(1, 2) = info.MapString("wonderful", 1); // Creates a new third category.
|
||||
m(1, 2) = info.MapString<double>("wonderful", 1); // Create new third category.
|
||||
m(2, 2) = 1;
|
||||
m(3, 2) = info.MapString("c", 1);
|
||||
m(3, 2) = info.MapString<double>("c", 1);
|
||||
m(4, 2) = 0;
|
||||
|
||||
// Save the modified matrix. Note that "wonderful" will be automatically
|
||||
// unmapped by `data::Save()`, as well as all other categorical values.
|
||||
mlpack::data::Save("mixed_string_data_mod.csv", m, info);
|
||||
// `m` can now be used with any mlpack algorithm that supports categorical data.
|
||||
```
|
||||
|
||||
Not every mlpack method supports categorical data. Below are the list of
|
||||
@@ -255,8 +256,10 @@ arma::Row<size_t> labels =
|
||||
|
||||
// Train in the constructor, using floating-point data.
|
||||
// The weak learner type is now a floating-point Perceptron.
|
||||
typedef Perceptron<SimpleWeightUpdate, ZeroInitialization, arma::fmat>
|
||||
PerceptronType;
|
||||
typedef mlpack::Perceptron<
|
||||
mlpack::SimpleWeightUpdate,
|
||||
mlpack::ZeroInitialization,
|
||||
arma::fmat> PerceptronType;
|
||||
mlpack::AdaBoost<PerceptronType, arma::fmat> ab(dataset, labels, 5);
|
||||
|
||||
// Create test data (500 points).
|
||||
|
||||
Reference in New Issue
Block a user