Merge pull request #6 from mlpack/master

update
This commit is contained in:
Keon Kim
2016-06-18 16:30:47 +09:00
committed by GitHub
32 changed files with 373 additions and 340 deletions
-5
View File
@@ -1,8 +1,3 @@
build*
*~
.*.swp
.*.swo
*.bak
src/mlpack/core/util/gitversion.hpp
src/mlpack/core/util/arma_config.hpp
+1 -1
View File
@@ -365,7 +365,7 @@ if (UNIX)
mlpack_adaboost
mlpack_kfn
mlpack_knn
mlpack_allkrann
mlpack_krann
mlpack_cf
mlpack_decision_stump
mlpack_det
+6 -3
View File
@@ -25,13 +25,16 @@
and MLPACK_VERSION_PATCH. The old names will remain in place until
mlpack 3.0.0.
* Renamed mlpack_allknn and mlpack_allkfn to mlpack_knn and mlpack_kfn. The
mlpack_allknn and mlpack_allkfn programs will remain as copies until mlpack
3.0.0.
* Renamed mlpack_allknn, mlpack_allkfn, and mlpack_allkrann to mlpack_knn,
mlpack_kfn, and mlpack_krann. The mlpack_allknn, mlpack_allkfn, and
mlpack_allkrann programs will remain as copies until mlpack 3.0.0.
* Add --random_initialization option to mlpack_hmm_train, for use when no
labels are provided.
* Add --kill_empty_clusters option to mlpack_kmeans and KillEmptyClusters
policy for the KMeans class (#595, #596).
### mlpack 2.0.1
###### 2016-02-04
* Fix CMake to properly detect when MKL is being used with Armadillo.
+1 -1
View File
@@ -51,7 +51,6 @@
* A full list of executables is given below:
*
* - mlpack_adaboost
* - mlpack_allkrann
* - mlpack_cf
* - mlpack_decision_stump
* - mlpack_det
@@ -69,6 +68,7 @@
* - mlpack_kfn
* - mlpack_kmeans
* - mlpack_knn
* - mlpack_krann
* - mlpack_lars
* - mlpack_linear_regression
* - mlpack_local_coordinate_coding
+12 -45
View File
@@ -6,16 +6,12 @@
*/
#include <list>
#include <boost/program_options.hpp>
#include <boost/any.hpp>
#include <boost/scoped_ptr.hpp>
#include <iostream>
#include <string>
#include "cli.hpp"
#include "log.hpp"
#include "option.hpp"
using namespace mlpack;
using namespace mlpack::util;
@@ -100,18 +96,19 @@ CLI::~CLI()
* @param alias An alias for the parameter.
* @param required Indicates if parameter must be set on command line.
*/
void CLI::Add(const std::string& path,
const std::string& description,
const std::string& alias,
bool required)
void CLI::Add(const std::string& identifier,
const std::string& description,
const std::string& alias,
bool required)
{
po::options_description& desc = CLI::GetSingleton().desc;
// Must make use of boost option name syntax.
std::string progOptId = alias.length() ? path + "," + alias : path;
std::string progOptId =
alias.length() ? identifier + "," + alias : identifier;
// Deal with a required alias.
AddAlias(alias, path);
AddAlias(alias, identifier);
// Add the option to boost::program_options.
desc.add_options()(progOptId.c_str(), description.c_str());
@@ -122,15 +119,15 @@ void CLI::Add(const std::string& path,
ParamData data;
data.desc = description;
data.tname = "";
data.name = path;
data.name = identifier;
data.isFlag = false;
data.wasPassed = false;
gmap[path] = data;
gmap[identifier] = data;
// If the option is required, add it to the required options list.
if (required)
GetSingleton().requiredOptions.push_front(path);
GetSingleton().requiredOptions.push_front(identifier);
return;
}
@@ -155,8 +152,8 @@ void CLI::AddAlias(const std::string& alias, const std::string& original)
* @brief Adds a flag parameter to CLI.
*/
void CLI::AddFlag(const std::string& identifier,
const std::string& description,
const std::string& alias)
const std::string& description,
const std::string& alias)
{
// Reuse functionality from Add().
Add(identifier, description, alias, false);
@@ -453,36 +450,6 @@ void CLI::RemoveDuplicateFlags(po::basic_parsed_options<char>& bpo)
}
}
/**
* Parses a stream for arguments
*
* @param stream The stream to be parsed.
*/
void CLI::ParseStream(std::istream& stream)
{
po::variables_map& vmap = GetSingleton().vmap;
po::options_description& desc = GetSingleton().desc;
// Parse the stream; place options & values into vmap.
try
{
po::store(po::parse_config_file(stream, desc), vmap);
}
catch (std::exception& ex)
{
Log::Fatal << ex.what() << std::endl;
}
// Flush the buffer; make sure changes are propagated to vmap.
po::notify(vmap);
UpdateGmap();
DefaultMessages();
RequiredOptions();
Timer::Start("total_time");
}
/* Prints out the current hierarchy. */
void CLI::Print()
{
+1 -17
View File
@@ -635,13 +635,6 @@ class CLI
*/
static void RemoveDuplicateFlags(po::basic_parsed_options<char>& bpo);
/**
* Parses a stream for arguments.
*
* @param stream The stream to be parsed.
*/
static void ParseStream(std::istream& stream);
/**
* Print out the current hierarchy.
*/
@@ -673,7 +666,7 @@ class CLI
//! Values of the options given by user.
po::variables_map vmap;
//! Pathnames of required options.
//! Identifier names of required options.
std::list<std::string> requiredOptions;
//! Map of global values.
@@ -728,15 +721,6 @@ class CLI
*/
static void RequiredOptions();
/**
* Cleans up input pathnames, rendering strings such as /foo/bar
* and foo/bar/ equivalent inputs.
*
* @param str Input string.
* @return Sanitized string.
*/
static std::string SanitizeString(const std::string& str);
/**
* Parses the values given on the command line, overriding any default values.
*/
+36 -9
View File
@@ -9,6 +9,7 @@
// In case it has not already been included.
#include "cli.hpp"
#include "prefixedoutstream.hpp"
// Include option.hpp here because it requires CLI but is also templated.
#include "option.hpp"
@@ -28,39 +29,65 @@ namespace mlpack {
* unless the parameter is specified.
*/
template<typename T>
void CLI::Add(const std::string& path,
void CLI::Add(const std::string& identifier,
const std::string& description,
const std::string& alias,
bool required)
{
// Temporarily define color code escape sequences.
#ifndef _WIN32
#define BASH_RED "\033[0;31m"
#define BASH_CLEAR "\033[0m"
#else
#define BASH_RED ""
#define BASH_CLEAR ""
#endif
// Temporary outstream object for detecting duplicate identifiers.
util::PrefixedOutStream outstr(std::cerr,
BASH_RED "[FATAL] " BASH_CLEAR, false, true /* fatal */);
#undef BASH_RED
#undef BASH_CLEAR
// Define identifier and alias maps.
gmap_t& gmap = GetSingleton().globalValues;
amap_t& amap = GetSingleton().aliasValues;
// If found in current map, print fatal error and terminate the program.
if (gmap.count(identifier))
outstr << "Parameter --" << identifier << "(-" << alias << ") "
<< "is defined multiple times with same identifiers." << std::endl;
if (amap.count(alias))
outstr << "Parameter --" << identifier << "(-" << alias << ") "
<< "is defined multiple times with same alias." << std::endl;
po::options_description& desc = CLI::GetSingleton().desc;
// Must make use of boost syntax here.
std::string progOptId = alias.length() ? path + "," + alias : path;
std::string progOptId =
alias.length() ? identifier + "," + alias : identifier;
// Add the alias, if necessary
AddAlias(alias, path);
AddAlias(alias, identifier);
// Add the option to boost program_options.
desc.add_options()(progOptId.c_str(), po::value<T>(), description.c_str());
// Make sure the appropriate metadata is inserted into gmap.
gmap_t& gmap = GetSingleton().globalValues;
ParamData data;
T tmp = T();
data.desc = description;
data.name = path;
data.name = identifier;
data.tname = TYPENAME(T);
data.value = boost::any(tmp);
data.wasPassed = false;
gmap[path] = data;
gmap[identifier] = data;
// If the option is required, add it to the required options list.
if (required)
GetSingleton().requiredOptions.push_front(path);
GetSingleton().requiredOptions.push_front(identifier);
}
// We specialize this in cli.cpp.
@@ -73,7 +100,7 @@ bool& CLI::GetParam<bool>(const std::string& identifier);
* more or less valid value is returned.
*
* @tparam T The type of the parameter.
* @param identifier The full pathname of the parameter.
* @param identifier The full name of the parameter.
*
* @return The value of the parameter. Use CLI::CheckValue to determine if it's
* valid.
+12 -12
View File
@@ -22,7 +22,7 @@ namespace ann /** Artificial Neural Network. */ {
* Implementation of a standard feed forward network.
*
* @tparam LayerTypes Contains all layer modules used to construct the network.
* @tparam OutputLayerType The outputlayer type used to evaluate the network.
* @tparam OutputLayerType The output layer type used to evaluate the network.
* @tparam InitializationRuleType Rule used to initialize the weight matrix.
* @tparam PerformanceFunction Performance strategy used to calculate the error.
*/
@@ -48,14 +48,14 @@ class FFN
* be used.
*
* @param network Network modules used to construct the network.
* @param outputLayer Outputlayer used to evaluate the network.
* @param outputLayer Output layer used to evaluate the network.
* @param predictors Input training variables.
* @param responses Outputs resulting from input training variables.
* @param optimizer Instantiated optimizer used to train the model.
* @param initializeRule Optional instantiated InitializationRule object
* for initializing the network paramter.
* for initializing the network parameter.
* @param performanceFunction Optional instantiated PerformanceFunction
* object used to claculate the error.
* object used to calculate the error.
*/
template<typename LayerType,
typename OutputType,
@@ -74,13 +74,13 @@ class FFN
* initialize rule and performance function should be used.
*
* @param network Network modules used to construct the network.
* @param outputLayer Outputlayer used to evaluate the network.
* @param outputLayer Output layer used to evaluate the network.
* @param predictors Input training variables.
* @param responses Outputs resulting from input training variables.
* @param initializeRule Optional instantiated InitializationRule object
* for initializing the network paramter.
* for initializing the network parameter.
* @param performanceFunction Optional instantiated PerformanceFunction
* object used to claculate the error.
* object used to calculate the error.
*/
template<typename LayerType, typename OutputType>
FFN(LayerType &&network,
@@ -96,11 +96,11 @@ class FFN
* training.
*
* @param network Network modules used to construct the network.
* @param outputLayer Outputlayer used to evaluate the network.
* @param outputLayer Output layer used to evaluate the network.
* @param initializeRule Optional instantiated InitializationRule object
* for initializing the network paramter.
* for initializing the network parameter.
* @param performanceFunction Optional instantiated PerformanceFunction
* object used to claculate the error.
* object used to calculate the error.
*/
template<typename LayerType, typename OutputType>
FFN(LayerType &&network,
@@ -408,10 +408,10 @@ private:
//! Instantiated feedforward network.
LayerTypes network;
//! The outputlayer used to evaluate the network
//! The output layer used to evaluate the network
OutputLayerType outputLayer;
//! Performance strategy used to claculate the error.
//! Performance strategy used to calculate the error.
PerformanceFunction performanceFunc;
//! The current evaluation mode (training or testing).
+10 -10
View File
@@ -24,7 +24,7 @@ namespace ann /** Artificial Neural Network. */ {
* Implementation of a standard recurrent neural network.
*
* @tparam LayerTypes Contains all layer modules used to construct the network.
* @tparam OutputLayerType The outputlayer type used to evaluate the network.
* @tparam OutputLayerType The output layer type used to evaluate the network.
* @tparam InitializationRuleType Rule used to initialize the weight matrix.
* @tparam PerformanceFunction Performance strategy used to calculate the error.
*/
@@ -50,14 +50,14 @@ class RNN
* be used.
*
* @param network Network modules used to construct the network.
* @param outputLayer Outputlayer used to evaluate the network.
* @param outputLayer Output layer used to evaluate the network.
* @param predictors Input training variables.
* @param responses Outputs resulting from input training variables.
* @param optimizer Instantiated optimizer used to train the model.
* @param initializeRule Optional instantiated InitializationRule object
* for initializing the network paramter.
* for initializing the network parameter.
* @param performanceFunction Optional instantiated PerformanceFunction
* object used to claculate the error.
* object used to calculate the error.
*/
template<typename LayerType,
typename OutputType,
@@ -76,13 +76,13 @@ class RNN
* initialize rule and performance function should be used.
*
* @param network Network modules used to construct the network.
* @param outputLayer Outputlayer used to evaluate the network.
* @param outputLayer Output layer used to evaluate the network.
* @param predictors Input training variables.
* @param responses Outputs resulting from input training variables.
* @param initializeRule Optional instantiated InitializationRule object
* for initializing the network paramter.
* for initializing the network parameter.
* @param performanceFunction Optional instantiated PerformanceFunction
* object used to claculate the error.
* object used to calculate the error.
*/
template<typename LayerType, typename OutputType>
RNN(LayerType &&network,
@@ -98,11 +98,11 @@ class RNN
* training.
*
* @param network Network modules used to construct the network.
* @param outputLayer Outputlayer used to evaluate the network.
* @param outputLayer Output layer used to evaluate the network.
* @param initializeRule Optional instantiated InitializationRule object
* for initializing the network paramter.
* for initializing the network parameter.
* @param performanceFunction Optional instantiated PerformanceFunction
* object used to claculate the error.
* object used to calculate the error.
*/
template<typename LayerType, typename OutputType>
RNN(LayerType &&network,
+1 -1
View File
@@ -85,7 +85,7 @@ PARAM_FLAG("all_user_recommendations", "Generate recommendations for all "
"users.", "A");
PARAM_STRING("output_file","File to save output recommendations to.", "o", "");
PARAM_INT("recommendations", "Number of recommendations to generate for each "
"query user.", "n", 5);
"query user.", "c", 5);
PARAM_INT("seed", "Set the random seed (0 uses std::time(NULL)).", "s", 0);
+1 -1
View File
@@ -133,7 +133,7 @@ int main(int argc, char *argv[])
Timer::Stop("det_training");
// Compute training set estimates, if desired.
if (CLI::GetParam<string>("training_set_estimates_file") != "")
if (CLI::HasParam("training_set_estimates_file"))
{
// Compute density estimates for each point in the training set.
arma::rowvec trainingDensities(trainingData.n_cols);
+14 -11
View File
@@ -34,8 +34,9 @@ PROGRAM_INFO("Fast Euclidean Minimum Spanning Tree", "This program can compute "
"column corresponds to the distance between the two points.");
PARAM_STRING_REQ("input_file", "Data input file.", "i");
PARAM_STRING("output_file", "Data output file. Stored as an edge list.", "o",
"emst_output.csv");
PARAM_STRING("output_file", "Data output file. Stored as an edge list.",
"o", "");
PARAM_FLAG("naive", "Compute the MST using O(n^2) naive algorithm.", "n");
PARAM_INT("leaf_size", "Leaf size in the kd-tree. One-element leaves give the "
"empirically best performance, but at the cost of greater memory "
@@ -51,10 +52,15 @@ int main(int argc, char* argv[])
{
CLI::ParseCommandLine(argc, argv);
const string dataFilename = CLI::GetParam<string>("input_file");
const string inputFile = CLI::GetParam<string>("input_file");
const string outputFile= CLI::GetParam<string>("output_file");
if (CLI::HasParam("output_file"))
Log::Warn << "--output_file (-o) is not specified; no results will be "
<< "saved!" << endl;
arma::mat dataPoints;
data::Load(dataFilename, dataPoints, true);
data::Load(inputFile, dataPoints, true);
// Do naive computation if necessary.
if (CLI::GetParam<bool>("naive"))
@@ -66,9 +72,8 @@ int main(int argc, char* argv[])
arma::mat naiveResults;
naive.ComputeMST(naiveResults);
const string outputFilename = CLI::GetParam<string>("output_file");
data::Save(outputFilename, naiveResults, true);
if (CLI::HasParam("output_file"))
data::Save(outputFile, naiveResults, true);
}
else
{
@@ -120,9 +125,7 @@ int main(int argc, char* argv[])
unmappedResults(2, i) = results(2, i);
}
// Output the results.
const string outputFilename = CLI::GetParam<string>("output_file");
data::Save(outputFilename, unmappedResults, true);
if (CLI::HasParam("output_file"))
data::Save(outputFile, unmappedResults, true);
}
}
+7 -4
View File
@@ -22,15 +22,17 @@ PROGRAM_INFO("GMM Sample Generator",
PARAM_STRING_REQ("input_model_file", "File containing input GMM model.", "m");
PARAM_INT_REQ("samples", "Number of samples to generate.", "n");
PARAM_STRING("output_file", "File to save output samples in.", "o",
"output.csv");
PARAM_STRING("output_file", "File to save output samples in.", "o", "");
PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0);
int main(int argc, char** argv)
{
CLI::ParseCommandLine(argc, argv);
if (CLI::HasParam("output_file"))
Log::Warn << "--output_file (-o) is not specified;"
<< "no results will be saved!" << endl;
if (CLI::GetParam<int>("seed") == 0)
mlpack::math::RandomSeed(time(NULL));
else
@@ -48,5 +50,6 @@ int main(int argc, char** argv)
for (size_t i = 0; i < length; ++i)
samples.col(i) = gmm.Random();
data::Save(CLI::GetParam<string>("output_file"), samples);
if (CLI::HasParam("output_file"))
data::Save(CLI::GetParam<string>("output_file"), samples);
}
@@ -22,18 +22,26 @@ PARAM_STRING_REQ("input_model_file", "File containing input GMM.", "m");
PARAM_STRING_REQ("input_file", "File containing points.", "i");
PARAM_STRING("output_file", "File to save calculated probabilities to.", "o",
"output.csv");
"");
int main(int argc, char** argv)
{
CLI::ParseCommandLine(argc, argv);
const string inputFile = CLI::GetParam<string>("input_file");
const string inputModelFile = CLI::GetParam<string>("input_model_file");
const string outputFile = CLI::GetParam<string>("input_model_file");
if (CLI::HasParam("output_file"))
Log::Warn << "--output_file (-o) is not specified;"
<< "no results will be saved!" << endl;
// Get the GMM and the points.
GMM gmm;
data::Load(CLI::GetParam<string>("input_model_file"), "gmm", gmm);
data::Load(inputFile, "gmm", gmm);
arma::mat dataset;
data::Load(CLI::GetParam<string>("input_file"), dataset);
data::Load(inputModelFile, dataset);
// Now calculate the probabilities.
arma::rowvec probabilities(dataset.n_cols);
@@ -41,5 +49,6 @@ int main(int argc, char** argv)
probabilities[i] = gmm.Probability(dataset.unsafe_col(i));
// And save the result.
data::Save(CLI::GetParam<string>("output_file"), probabilities);
if (CLI::HasParam("output_file"))
data::Save(outputFile, probabilities);
}
+10 -6
View File
@@ -22,9 +22,8 @@ PROGRAM_INFO("Hidden Markov Model (HMM) Sequence Generator", "This "
PARAM_STRING_REQ("model_file", "File containing HMM.", "m");
PARAM_INT_REQ("length", "Length of sequence to generate.", "l");
PARAM_STRING("output_file", "File to save observation sequence to.", "o" ,"");
PARAM_INT("start_state", "Starting state of sequence.", "t", 0);
PARAM_STRING("output_file", "File to save observation sequence to.", "o",
"output.csv");
PARAM_STRING("state_file", "File to save hidden state sequence to (may be left "
"unspecified.", "S", "");
PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0);
@@ -51,6 +50,8 @@ struct Generate
// Load the parameters.
const size_t startState = (size_t) CLI::GetParam<int>("start_state");
const size_t length = (size_t) CLI::GetParam<int>("length");
const string outputFile = CLI::GetParam<string>("output_file");
const string sequenceFile = CLI::GetParam<string>("state_file");
Log::Info << "Generating sequence of length " << length << "..." << endl;
if (startState >= hmm.Transition().n_rows)
@@ -61,12 +62,11 @@ struct Generate
hmm.Generate(length, observations, sequence, startState);
// Now save the output.
const string outputFile = CLI::GetParam<string>("output_file");
data::Save(outputFile, observations, true);
if (CLI::HasParam("output_file"))
data::Save(outputFile, observations, true);
// Do we want to save the hidden sequence?
const string sequenceFile = CLI::GetParam<string>("state_file");
if (sequenceFile != "")
if (CLI::HasParam("state_file"))
data::Save(sequenceFile, sequence, true);
}
};
@@ -76,6 +76,10 @@ int main(int argc, char** argv)
// Parse command line options.
CLI::ParseCommandLine(argc, argv);
if (CLI::HasParam("output_file"))
Log::Warn << "--output_file (-o) is not specified; no results will be "
<< "saved!" << endl;
// Set random seed.
if (CLI::GetParam<int>("seed") != 0)
RandomSeed((size_t) CLI::GetParam<int>("seed"));
+3 -4
View File
@@ -45,8 +45,7 @@ PARAM_INT("gaussians", "Number of gaussians in each GMM (necessary when type is"
PARAM_STRING("model_file", "Pre-existing HMM model (optional).", "m", "");
PARAM_STRING("labels_file", "Optional file of hidden states, used for "
"labeled training.", "l", "");
PARAM_STRING("output_model_file", "File to save trained HMM to.", "o",
"output_hmm.xml");
PARAM_STRING("output_model_file", "File to save trained HMM to.", "o", "");
PARAM_INT("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0);
PARAM_DOUBLE("tolerance", "Tolerance of the Baum-Welch algorithm.", "T", 1e-5);
PARAM_FLAG("random_initialization", "Initialize emissions and transition "
@@ -88,7 +87,7 @@ struct Train
<< endl;
vector<arma::Row<size_t>> labelSeq; // May be empty.
if (labelsFile != "")
if (CLI::HasParam("labels_file"))
{
// Do we have multiple label files to load?
char lineBuf[1024];
@@ -271,7 +270,7 @@ int main(int argc, char** argv)
}
// If we have a model file, we can autodetect the type.
if (modelFile != "")
if (CLI::HasParam("model_file"))
{
LoadHMMAndPerformAction<Train>(modelFile, &trainSeq);
}
+9 -4
View File
@@ -20,8 +20,8 @@ PROGRAM_INFO("Hidden Markov Model (HMM) Viterbi State Prediction", "This "
PARAM_STRING_REQ("input_file", "File containing observations,", "i");
PARAM_STRING_REQ("model_file", "File containing HMM.", "m");
PARAM_STRING("output_file", "File to save predicted state sequence to.", "o",
"output.csv");
PARAM_STRING("output_file", "File to save predicted state sequence to.",
"o", "");
using namespace mlpack;
using namespace mlpack::hmm;
@@ -40,6 +40,7 @@ struct Viterbi
{
// Load observations.
const string inputFile = CLI::GetParam<string>("input_file");
const string outputFile = CLI::GetParam<string>("output_file");
mat dataSeq;
data::Load(inputFile, dataSeq, true);
@@ -62,8 +63,8 @@ struct Viterbi
hmm.Predict(dataSeq, sequence);
// Save output.
const string outputFile = CLI::GetParam<string>("output_file");
data::Save(outputFile, sequence, true);
if (CLI::HasParam("output_file"))
data::Save(outputFile, sequence, true);
}
};
@@ -72,6 +73,10 @@ int main(int argc, char** argv)
// Parse command line options.
CLI::ParseCommandLine(argc, argv);
if (CLI::HasParam("output_file"))
Log::Warn << "--output_file (-o) is not specified; no results will be "
<< "saved!" << endl;
const string modelFile = CLI::GetParam<string>("model_file");
LoadHMMAndPerformAction<Viterbi>(modelFile);
}
@@ -56,10 +56,10 @@ PARAM_STRING("output_model_file", "File to save trained tree to.", "M", "");
PARAM_STRING("test_file", "File of testing data.", "T", "");
PARAM_STRING("test_labels_file", "Labels of test data.", "L", "");
PARAM_STRING("predictions_file", "File to output label predictions for test "
"data into.", "p", "");
PARAM_STRING("probabilities_file", "In addition to predicting labels, provide "
"prediction probabilities in this file.", "P", "");
PARAM_STRING("predictions_file", "File to output label predictions for"
"test data into.", "p", "");
PARAM_STRING("probabilities_file", "In addition to predicting labels, "
"provide prediction probabilities in this file.", "P", "");
PARAM_STRING("numeric_split_strategy", "The splitting strategy to use for "
"numeric features: 'domingos' or 'binary'.", "N", "binary");
@@ -90,25 +90,28 @@ int main(int argc, char** argv)
const string labelsFile = CLI::GetParam<string>("labels_file");
const string inputModelFile = CLI::GetParam<string>("input_model_file");
const string testFile = CLI::GetParam<string>("test_file");
const string predictionsFile = CLI::GetParam<string>("predictions_file");
const string probabilitiesFile = CLI::GetParam<string>("probabilities_file");
const string predictionsFile =
CLI::GetParam<string>("predictions_file");
const string probabilitiesFile =
CLI::GetParam<string>("probabilities_file");
const string numericSplitStrategy =
CLI::GetParam<string>("numeric_split_strategy");
if ((!predictionsFile.empty() || !probabilitiesFile.empty()) &&
testFile.empty())
if ((CLI::HasParam("predictions_file") ||
CLI::HasParam("probabilities_file")) &&
!CLI::HasParam("test_file"))
Log::Fatal << "--test_file must be specified if --predictions_file or "
<< "--probabilities_file is specified." << endl;
if (trainingFile.empty() && inputModelFile.empty())
if (!CLI::HasParam("training_file") && !CLI::HasParam("input_model_file"))
Log::Fatal << "One of --training_file or --input_model_file must be "
<< "specified!" << endl;
if (!trainingFile.empty() && labelsFile.empty())
if (CLI::HasParam("training_file") && !CLI::HasParam("labels_file"))
Log::Fatal << "If --training_file is specified, --labels_file must be "
<< "specified too!" << endl;
if (trainingFile.empty() && CLI::HasParam("batch_mode"))
if (!CLI::HasParam("training_file") && CLI::HasParam("batch_mode"))
Log::Warn << "--batch_mode (-b) ignored; no training set provided." << endl;
if (CLI::HasParam("passes") && CLI::HasParam("batch_mode"))
@@ -177,8 +180,10 @@ void PerformActions(const typename TreeType::NumericSplit& numericSplit)
const string inputModelFile = CLI::GetParam<string>("input_model_file");
const string outputModelFile = CLI::GetParam<string>("output_model_file");
const string testFile = CLI::GetParam<string>("test_file");
const string predictionsFile = CLI::GetParam<string>("predictions_file");
const string probabilitiesFile = CLI::GetParam<string>("probabilities_file");
const string predictionsFile =
CLI::GetParam<string>("predictions_file");
const string probabilitiesFile =
CLI::GetParam<string>("probabilities_file");
bool batchTraining = CLI::HasParam("batch_mode");
const size_t passes = (size_t) CLI::GetParam<int>("passes");
if (passes > 1)
@@ -186,7 +191,7 @@ void PerformActions(const typename TreeType::NumericSplit& numericSplit)
TreeType* tree = NULL;
DatasetInfo datasetInfo;
if (inputModelFile.empty())
if (!CLI::HasParam("input_model_file"))
{
arma::mat trainingSet;
data::Load(trainingFile, trainingSet, datasetInfo, true);
@@ -216,7 +221,7 @@ void PerformActions(const typename TreeType::NumericSplit& numericSplit)
tree = new TreeType(datasetInfo, 1, 1);
data::Load(inputModelFile, "streamingDecisionTree", *tree, true);
if (!trainingFile.empty())
if (CLI::HasParam("training_file"))
{
arma::mat trainingSet;
data::Load(trainingFile, trainingSet, datasetInfo, true);
@@ -244,7 +249,7 @@ void PerformActions(const typename TreeType::NumericSplit& numericSplit)
}
}
if (!trainingFile.empty())
if (CLI::HasParam("training_file"))
{
// Get training error.
arma::mat trainingSet;
@@ -282,7 +287,7 @@ void PerformActions(const typename TreeType::NumericSplit& numericSplit)
Log::Info << nodes << " nodes in the tree." << endl;
// The tree is trained or loaded. Now do any testing if we need.
if (!testFile.empty())
if (CLI::HasParam("test_file"))
{
arma::mat testSet;
data::Load(testFile, testSet, datasetInfo, true);
@@ -312,15 +317,15 @@ void PerformActions(const typename TreeType::NumericSplit& numericSplit)
100.0 << ")." << endl;
}
if (!predictionsFile.empty())
if (CLI::HasParam("predictions_file"))
data::Save(predictionsFile, predictions);
if (!probabilitiesFile.empty())
if (CLI::HasParam("probabilities_file"))
data::Save(probabilitiesFile, probabilities);
}
// Check the accuracy on the training set.
if (!outputModelFile.empty())
if (CLI::HasParam("output_model_file"))
data::Save(outputModelFile, "streamingDecisionTree", *tree, true);
// Clean up memory.
+22 -15
View File
@@ -51,8 +51,8 @@ PARAM_STRING("output_model_file", "File to save model to.", "M", "");
PARAM_STRING("test_file", "File containing points to regress on (test points).",
"t", "");
PARAM_STRING("output_predictions", "If --test_file is specified, this file is "
"where the predicted responses will be saved.", "o", "predictions.csv");
PARAM_STRING("output_predictions", "If --test_file is specified, this "
"file is where the predicted responses will be saved.", "o", "");
PARAM_DOUBLE("lambda1", "Regularization parameter for l1-norm penalty.", "l",
0);
@@ -95,12 +95,16 @@ int main(int argc, char* argv[])
if (!CLI::HasParam("output_predictions") &&
!CLI::HasParam("output_model_file"))
Log::Warn << "--output_predictions (-o) and --output_model_file (-M) are "
<< "not specified; no results will be saved!" << endl;
Log::Warn << "--output_predictions (-o) and --output_model_file (-M) "
<< "are not specified; no results will be saved!" << endl;
if (CLI::HasParam("output_predictions") && !CLI::HasParam("test_file"))
Log::Warn << "--output_predictions (-o) specified, but --test_file (-t) is "
<< "not; no results will be saved." << endl;
Log::Warn << "--output_predictions (-o) specified, but --test_file "
<< "(-t) is not; no results will be saved." << endl;
if (CLI::HasParam("test_file") && !CLI::HasParam("output_predictions"))
Log::Warn << "--test_file (-t) specified, but --output_predictions "
<< "(-o) is not; no results will be saved." << endl;
// Initialize the object.
LARS lars(useCholesky, lambda1, lambda2);
@@ -109,16 +113,16 @@ int main(int argc, char* argv[])
{
// Load covariates. We can avoid LARS transposing our data by choosing to
// not transpose this data.
const string matXFilename = CLI::GetParam<string>("input_file");
const string inputFile = CLI::GetParam<string>("input_file");
mat matX;
data::Load(matXFilename, matX, true, false);
data::Load(inputFile, matX, true, false);
// Load responses. The responses should be a one-dimensional vector, and it
// seems more likely that these will be stored with one response per line
// (one per row). So we should not transpose upon loading.
const string yFilename = CLI::GetParam<string>("responses_file");
const string responsesFile = CLI::GetParam<string>("responses_file");
mat matY; // Will be a vector.
data::Load(yFilename, matY, true, false);
data::Load(responsesFile, matY, true, false);
// Make sure y is oriented the right way.
if (matY.n_rows == 1)
@@ -135,16 +139,14 @@ int main(int argc, char* argv[])
}
else // We must have --input_model_file.
{
const string modelFile = CLI::GetParam<string>("input_model_file");
data::Load(modelFile, "lars_model", lars, true);
const string inputModelFile = CLI::GetParam<string>("input_model_file");
data::Load(inputModelFile, "lars_model", lars, true);
}
if (CLI::HasParam("test_file"))
{
Log::Info << "Regressing on test points." << endl;
const string testFile = CLI::GetParam<string>("test_file");
const string outputPredictionsFile =
CLI::GetParam<string>("output_predictions");
// Load test points.
mat testPoints;
@@ -161,7 +163,12 @@ int main(int argc, char* argv[])
lars.Predict(testPoints.t(), predictions, false);
// Save test predictions. One per line, so, don't transpose on save.
data::Save(outputPredictionsFile, predictions, true, false);
if (CLI::HasParam("output_predictions"))
{
const string outputPredictionsFile =
CLI::GetParam<string>("output_predictions");
data::Save(outputPredictionsFile, predictions, true, false);
}
}
if (CLI::HasParam("output_model_file"))
@@ -22,22 +22,23 @@ PROGRAM_INFO("Simple Linear Regression and Prediction",
" another matrix X' (--test_file):\n\n"
" y' = X' * b\n\n"
"and these predicted responses, y', are saved to a file "
"(--output_predictions). This type of regression is related to least-angle"
" regression, which mlpack implements with the 'lars' executable.");
"(--output_predictions). This type of regression is related to "
"least-angle regression, which mlpack implements with the 'lars' "
"executable.");
PARAM_STRING("training_file", "File containing training set X (regressors).",
"t", "");
PARAM_STRING("training_responses", "Optional file containing y (responses). If "
"not given, the responses are assumed to be the last row of the input "
"file.", "r", "");
PARAM_STRING("training_responses", "Optional file containing y "
"(responses). If not given, the responses are assumed to be the last row "
"of the input file.", "r", "");
PARAM_STRING("input_model_file", "File containing existing model (parameters).",
"m", "");
PARAM_STRING("output_model_file", "File to save trained model to.", "M", "");
PARAM_STRING("test_file", "File containing X' (test regressors).", "T", "");
PARAM_STRING("output_predictions", "If --test_file is specified, this file is "
"where the predicted responses will be saved.", "p", "predictions.csv");
PARAM_STRING("output_predictions", "If --test_file is specified, this "
"file is where the predicted responses will be saved.", "p", "");
PARAM_DOUBLE("lambda", "Tikhonov regularization for ridge regression. If 0, "
"the method reduces to linear regression.", "l", 0.0);
@@ -54,10 +55,12 @@ int main(int argc, char* argv[])
const string inputModelFile = CLI::GetParam<string>("input_model_file");
const string outputModelFile = CLI::GetParam<string>("output_model_file");
const string outputPredictions = CLI::GetParam<string>("output_predictions");
const string responseName = CLI::GetParam<string>("training_responses");
const string testName = CLI::GetParam<string>("test_file");
const string trainName = CLI::GetParam<string>("training_file");
const string outputPredictionsFile =
CLI::GetParam<string>("output_predictions");
const string trainingResponsesFile =
CLI::GetParam<string>("training_responses");
const string testFile = CLI::GetParam<string>("test_file");
const string trainFile = CLI::GetParam<string>("training_file");
const double lambda = CLI::GetParam<double>("lambda");
mat regressors;
@@ -69,16 +72,16 @@ int main(int argc, char* argv[])
bool computeModel = false;
// We want to determine if an input file XOR model file were given.
if (trainName.empty()) // The user specified no input file.
if (!CLI::HasParam("training_file"))
{
if (inputModelFile.empty()) // The user specified no model file; error.
if (!CLI::HasParam("input_model_file"))
Log::Fatal << "You must specify either --input_file or --model_file."
<< endl;
else // The model file was specified, no problems.
computeModel = false;
}
// The user specified an input file but no model file, no problems.
else if (inputModelFile.empty())
else if (!CLI::HasParam("input_model_file"))
computeModel = true;
// The user specified both an input file and model file.
// This is ambiguous -- which model should we use? A generated one or given
@@ -89,9 +92,13 @@ int main(int argc, char* argv[])
<< "both." << endl;
}
if (CLI::HasParam("test_file") && !CLI::HasParam("output_predictions"))
Log::Warn << "--test_file (-t) specified, but --output_predictions "
<< "(-o) is not; no results will be saved." << endl;
// If they specified a model file, we also need a test file or we
// have nothing to do.
if (!computeModel && testName.empty())
if (!computeModel && !CLI::HasParam("test_file"))
{
Log::Fatal << "When specifying --model_file, you must also specify "
<< "--test_file." << endl;
@@ -106,11 +113,11 @@ int main(int argc, char* argv[])
if (computeModel)
{
Timer::Start("load_regressors");
data::Load(trainName, regressors, true);
data::Load(trainFile, regressors, true);
Timer::Stop("load_regressors");
// Are the responses in a separate file?
if (responseName.empty())
if (CLI::HasParam("training_responses"))
{
// The initial predictors for y, Nx1.
responses = trans(regressors.row(regressors.n_rows - 1));
@@ -120,7 +127,7 @@ int main(int argc, char* argv[])
{
// The initial predictors for y, Nx1.
Timer::Start("load_responses");
data::Load(responseName, responses, true);
data::Load(trainingResponsesFile, responses, true);
Timer::Stop("load_responses");
if (responses.n_rows == 1)
@@ -139,12 +146,12 @@ int main(int argc, char* argv[])
Timer::Stop("regression");
// Save the parameters.
if (!outputModelFile.empty())
if (CLI::HasParam("output_model_file"))
data::Save(outputModelFile, "linearRegressionModel", lr);
}
// Did we want to predict, too?
if (!testName.empty())
if (CLI::HasParam("test_file"))
{
// A model file was passed in, so load it.
if (!computeModel)
@@ -157,14 +164,14 @@ int main(int argc, char* argv[])
// Load the test file data.
arma::mat points;
Timer::Start("load_test_points");
data::Load(testName, points, true);
data::Load(testFile, points, true);
Timer::Stop("load_test_points");
// Ensure that test file data has the right number of features.
if ((lr.Parameters().n_elem - 1) != points.n_rows)
{
Log::Fatal << "The model was trained on " << lr.Parameters().n_elem - 1
<< "-dimensional data, but the test points in '" << testName
<< "-dimensional data, but the test points in '" << testFile
<< "' are " << points.n_rows << "-dimensional!" << endl;
}
@@ -175,6 +182,7 @@ int main(int argc, char* argv[])
Timer::Stop("prediction");
// Save predictions.
data::Save(outputPredictions, predictions, true, false);
if (CLI::HasParam("output_predictions"))
data::Save(outputPredictionsFile, predictions, true, false);
}
}
+11 -7
View File
@@ -18,8 +18,7 @@ PROGRAM_INFO("Maximum Variance Unfolding (MVU)", "This program implements "
PARAM_STRING_REQ("input_file", "Filename of input dataset.", "i");
PARAM_INT_REQ("new_dim", "New dimensionality of dataset.", "d");
PARAM_STRING("output_file", "Filename to save unfolded dataset to.", "o",
"output.csv");
PARAM_STRING("output_file", "Filename to save unfolded dataset to.", "o", "");
PARAM_INT("num_neighbors", "Number of nearest neighbors to consider while "
"unfolding.", "k", 5);
@@ -33,16 +32,22 @@ int main(int argc, char **argv)
{
// Read from command line.
CLI::ParseCommandLine(argc, argv);
const string inputFile = CLI::GetParam<string>("input_file");
const string outputFile = CLI::GetParam<string>("output_file");
const int newDim = CLI::GetParam<int>("new_dim");
const int numNeighbors = CLI::GetParam<int>("num_neighbors");
if (CLI::HasParam("output_file"))
Log::Warn << "--output_file (-o) is not specified; no results will be "
<< "saved!" << endl;
RandomSeed(time(NULL));
// Load input dataset.
const string inputFile = CLI::GetParam<string>("input_file");
mat data;
data::Load(inputFile, data, true);
// Verify that the requested dimensionality is valid.
const int newDim = CLI::GetParam<int>("new_dim");
if (newDim <= 0 || newDim > (int) data.n_rows)
{
Log::Fatal << "Invalid new dimensionality (" << newDim << "). Must be "
@@ -51,7 +56,6 @@ int main(int argc, char **argv)
}
// Verify that the number of neighbors is valid.
const int numNeighbors = CLI::GetParam<int>("num_neighbors");
if (numNeighbors <= 0 || numNeighbors > (int) data.n_cols)
{
Log::Fatal << "Invalid number of neighbors (" << numNeighbors << "). Must "
@@ -66,6 +70,6 @@ int main(int argc, char **argv)
mvu.Unfold(newDim, numNeighbors, output);
// Save results to file.
const string outputFile = CLI::GetParam<string>("output_file");
data::Save(outputFile, output, true);
if (CLI::HasParam("output_file"))
data::Save(outputFile, output, true);
}
@@ -33,22 +33,22 @@ add_cli_executable(knn)
add_cli_executable(kfn)
if (BUILD_CLI_EXECUTABLES)
# -- mlpack_knn/mlpack_kfn compatibility start --
# Make a copy of mlpack_knn/mlpack_kfn both on Windows and *unix for
# compatibility. This should be removed by mlpack 3.0.0.
get_property(knn_loc TARGET mlpack_knn PROPERTY LOCATION)
get_filename_component(knn_ext ${knn_loc} EXT)
# -- mlpack_knn/mlpack_kfn compatibility start --
# Make a copy of mlpack_knn/mlpack_kfn both on Windows and *unix for
# compatibility. This should be removed by mlpack 3.0.0.
get_property(knn_loc TARGET mlpack_knn PROPERTY LOCATION)
get_filename_component(knn_ext ${knn_loc} EXT)
add_custom_command(TARGET mlpack_knn POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:mlpack_knn> $<TARGET_FILE_DIR:mlpack_knn>/mlpack_allknn${knn_ext}
)
add_custom_command(TARGET mlpack_knn POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:mlpack_knn> $<TARGET_FILE_DIR:mlpack_knn>/mlpack_allknn${knn_ext}
)
get_property(kfn_loc TARGET mlpack_kfn PROPERTY LOCATION)
get_filename_component(kfn_ext ${kfn_loc} EXT)
get_property(kfn_loc TARGET mlpack_kfn PROPERTY LOCATION)
get_filename_component(kfn_ext ${kfn_loc} EXT)
add_custom_command(TARGET mlpack_kfn POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:mlpack_kfn> $<TARGET_FILE_DIR:mlpack_kfn>/mlpack_allkfn${kfn_ext}
)
add_custom_command(TARGET mlpack_kfn POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:mlpack_kfn> $<TARGET_FILE_DIR:mlpack_kfn>/mlpack_allkfn${kfn_ext}
)
endif ()
+4 -3
View File
@@ -22,10 +22,11 @@ PROGRAM_INFO("Principal Components Analysis", "This program performs principal "
// Parameters for program.
PARAM_STRING_REQ("input_file", "Input dataset to perform PCA on.", "i");
PARAM_STRING_REQ("output_file", "File to save modified dataset to.", "o");
PARAM_INT("new_dimensionality", "Desired dimensionality of output dataset. If "
"0, no dimensionality reduction is performed.", "d", 0);
PARAM_DOUBLE("var_to_retain", "Amount of variance to retain; should be between "
"0 and 1. If 1, all variance is retained. Overrides -d.", "V", 0);
"0 and 1. If 1, all variance is retained. Overrides -d.", "r", 0);
PARAM_FLAG("scale", "If set, the data will be scaled before running PCA, such "
"that the variance of each feature is 1.", "s");
@@ -64,8 +65,8 @@ int main(int argc, char** argv)
if (CLI::GetParam<double>("var_to_retain") != 0)
{
if (CLI::GetParam<int>("new_dimensionality") != 0)
Log::Warn << "New dimensionality (-d) ignored because -V was specified."
<< endl;
Log::Warn << "New dimensionality (-d) ignored because --var_to_retain was"
<< " specified." << endl;
varRetained = p.Apply(dataset, CLI::GetParam<double>("var_to_retain"));
}
@@ -112,21 +112,24 @@ int main(int argc, char** argv)
const size_t maxIterations = (size_t) CLI::GetParam<int>("max_iterations");
// We must either load a model or train a model.
if (inputModelFile == "" && trainingDataFile == "")
if (!CLI::HasParam("input_model_file") && !CLI::HasParam("training_file"))
Log::Fatal << "Either an input model must be specified with "
<< "--input_model_file or training data must be given "
<< "(--training_file)!" << endl;
// If the user isn't going to save the output model or any predictions, we
// should issue a warning.
if (outputModelFile == "" && testDataFile == "")
if (!CLI::HasParam("output_model_file") && !CLI::HasParam("test_file"))
Log::Warn << "Output will not be saved! (Neither --test_file nor "
<< "--output_model_file are specified.)" << endl;
if (CLI::HasParam("test_file") && !CLI::HasParam("output_file"))
Log::Fatal << "--output_file must be specified with --test_file" << endl;
// Now, load our model, if there is one.
Perceptron<>* p = NULL;
Col<size_t> mappings;
if (inputModelFile != "")
if (CLI::HasParam("input_model_file"))
{
Log::Info << "Loading saved perceptron from model file '" << inputModelFile
<< "'." << endl;
@@ -139,7 +142,7 @@ int main(int argc, char** argv)
}
// Next, load the training data and labels (if they have been given).
if (trainingDataFile != "")
if (CLI::HasParam("training_file"))
{
Log::Info << "Training perceptron on dataset '" << trainingDataFile;
if (labelsFile != "")
@@ -217,7 +220,7 @@ int main(int argc, char** argv)
}
// Now, the training procedure is complete. Do we have any test data?
if (testDataFile != "")
if (CLI::HasParam("test_file"))
{
Log::Info << "Classifying dataset '" << testDataFile << "'." << endl;
mat testData;
@@ -245,7 +248,7 @@ int main(int argc, char** argv)
}
// Lastly, do we need to save the output model?
if (outputModelFile != "")
if (CLI::HasParam("output_model_file"))
{
PerceptronModel pm(*p, mappings);
data::Save(outputModelFile, "perceptron_model", pm);
@@ -14,26 +14,20 @@ PROGRAM_INFO("Split Data", "This utility takes a dataset and optionally labels "
"(-r) option; the default is 0.2 (20%)."
"\n\n"
"The program does not modify the original file, but instead makes separate "
"files to save the training and test files; you can specify the file names "
"with --training_file (-t) and --test_file (-T). If these options are not "
"specified, the program automatically names the training and test file by "
"prepending 'train_' and 'test_' to the dataset filename (which was "
"specified by --input_file)."
"files to save the training and test files; The program requires you to "
"specify the file names with --training_file (-t) and --test_file (-T)."
"\n\n"
"Optionally, labels can be also be split along with the data by specifying "
"the --input_labels_file (-I) option. Splitting labels works the same way "
"as splitting the data. The output training and test labels will be saved "
"to the files specified by --training_labels_file (-l) and "
"--test_labels_file (-L), respectively. If these options are not specified,"
" then the program will automatically name the training labels and test "
"labels file by prepending 'train_' and 'test_' to the labels filename "
"(which was specified by --input_labels_file)."
"--test_labels_file (-L), respectively."
"\n\n"
"So, a simple example where we want to split dataset.csv into "
"train_dataset.csv and test_dataset.csv with 60% of the data in the "
"training set and 40% of the dataset in the test set, we could run"
"train.csv and test.csv with 60% of the data in the training set and 40% "
"of the dataset in the test set, we could run"
"\n\n"
"$ mlpack_preprocess_split -i dataset.csv -r 0.4"
"$ mlpack_preprocess_split -i dataset.csv -t train.csv -T test.csv -r 0.4"
"\n\n"
"If we had a dataset in dataset.csv and associated labels in labels.csv, "
"and we wanted to split these into training_set.csv, training_labels.csv, "
@@ -46,12 +40,12 @@ PROGRAM_INFO("Split Data", "This utility takes a dataset and optionally labels "
// Define parameters for data.
PARAM_STRING_REQ("input_file", "File containing data,", "i");
PARAM_STRING_REQ("training_file", "File name to save train data", "t");
PARAM_STRING_REQ("test_file", "File name to save test data", "T");
// Define optional parameters.
PARAM_STRING("input_labels_file", "File containing labels", "I", "");
PARAM_STRING("training_file", "File name to save train data", "t", "");
PARAM_STRING("test_file", "File name to save test data", "T", "");
PARAM_STRING("training_labels_file", "File name to save train label", "l", "");
PARAM_STRING("test_labels_file", "File name to save test label", "L", "");
PARAM_STRING("test_labels_file", "File name to save test label", "L","");
// Define optional test ratio, default is 0.2 (Test 20% Train 80%)
PARAM_DOUBLE("test_ratio", "Ratio of test set, if not set,"
@@ -67,52 +61,33 @@ int main(int argc, char** argv)
CLI::ParseCommandLine(argc, argv);
const string inputFile = CLI::GetParam<string>("input_file");
const string inputLabels = CLI::GetParam<string>("input_labels_file");
string trainingFile = CLI::GetParam<string>("training_file");
string testFile = CLI::GetParam<string>("test_file");
string trainingLabelsFile = CLI::GetParam<string>("training_labels_file");
string testLabelsFile = CLI::GetParam<string>("test_labels_file");
const string trainingFile = CLI::GetParam<string>("training_file");
const string testFile = CLI::GetParam<string>("test_file");
const string trainingLabelsFile = CLI::GetParam<string>("training_labels_file");
const string testLabelsFile = CLI::GetParam<string>("test_labels_file");
const double testRatio = CLI::GetParam<double>("test_ratio");
// Check on data parameters.
if (trainingFile.empty())
{
trainingFile = "train_" + inputFile;
Log::Warn << "You did not specify --training_file, so the training set file"
<< " name will be automatically set to '" << trainingFile << "'."
<< endl;
}
if (testFile.empty())
{
testFile = "test_" + inputFile;
Log::Warn << "You did not specify --test_file, so the test set file name "
<< "will be automatically set to '" << testFile << "'." << endl;
}
// Check on label parameters.
if (!inputLabels.empty())
if (CLI::HasParam("input_labels"))
{
if (!CLI::HasParam("training_labels_file"))
{
trainingLabelsFile = "train_" + inputLabels;
Log::Warn << "You did not specify --training_labels_file, so the training"
<< "set labels file name will be automatically set to '"
<< trainingLabelsFile << "'." << endl;
Log::Fatal << "--training_labels_file (-l) must be specified if "
<< "--input_labels (-l) is specified!" << endl;
}
if (!CLI::HasParam("test_labels_file"))
{
testLabelsFile = "test_" + inputLabels;
Log::Warn << "You did not specify --test_labels_file, so the test set "
<< "labels file name will be automatically set to '"
<< testLabelsFile << "'." << endl;
Log::Fatal << "--test_labels_file (-L) must be specified if "
<< "--input_labels (-I) is specified!" << endl;
}
}
else
{
if (CLI::HasParam("training_labels_file")
|| CLI::HasParam("test_labels_file"))
if (CLI::HasParam("training_labels_file") ||
CLI::HasParam("test_labels_file"))
{
Log::Fatal << "When specifying --training_labels_file or "
<< "--test_labels_file, you must also specify --input_labels. "
<< "--test_labels_file, you must also specify --input_labels."
<< endl;
}
}
+2 -4
View File
@@ -16,10 +16,8 @@ PROGRAM_INFO("RADICAL", "An implementation of RADICAL, a method for independent"
PARAM_STRING_REQ("input_file", "Input dataset filename for ICA.", "i");
PARAM_STRING("output_ic", "File to save independent components to.", "o",
"output_ic.csv");
PARAM_STRING("output_unmixing", "File to save unmixing matrix to.", "u",
"output_unmixing.csv");
PARAM_STRING_REQ("output_ic", "File to save independent components to.", "o");
PARAM_STRING_REQ("output_unmixing", "File to save unmixing matrix to.", "u");
PARAM_DOUBLE("noise_std_dev", "Standard deviation of Gaussian noise.", "n",
0.175);
+16 -4
View File
@@ -30,10 +30,22 @@ set(DIR_SRCS)
foreach(file ${SOURCES})
set(DIR_SRCS ${DIR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${file})
endforeach()
# append sources (with directory name) to list of all mlpack sources (used at the parent scope)
# Append sources (with directory name) to list of all mlpack sources (used at the parent scope)
set(MLPACK_SRCS ${MLPACK_SRCS} ${DIR_SRCS} PARENT_SCOPE)
# The code to compute the rank-approximate neighbor for the given query and
# reference sets.
add_cli_executable(krann)
if (BUILD_CLI_EXECUTABLES)
# Compatibility: retain mlpack_allkrann until mlpack 3.0.0.
get_property(krann_loc TARGET mlpack_krann PROPERTY LOCATION)
get_filename_component(krann_ext ${krann_loc} EXT)
add_custom_command(TARGET mlpack_krann POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:mlpack_krann>
$<TARGET_FILE_DIR:mlpack_krann>/mlpack_allkrann${kfn_ext}
)
endif ()
# The code to compute the rank-approximate neighbor
# for the given query and reference sets
add_cli_executable(allkrann)
@@ -2,7 +2,7 @@
* @file allkrann_main.cpp
* @author Parikshit Ram
*
* Implementation of the AllkRANN executable. Allows some number of standard
* Implementation of the kRANN executable. Allows some number of standard
* options.
*/
#include <mlpack/core.hpp>
@@ -18,7 +18,7 @@ using namespace mlpack::tree;
using namespace mlpack::metric;
// Information about the program itself.
PROGRAM_INFO("All K-Rank-Approximate-Nearest-Neighbors",
PROGRAM_INFO("K-Rank-Approximate-Nearest-Neighbors (kRANN)",
"This program will calculate the k rank-approximate-nearest-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 "
@@ -73,7 +73,7 @@ PARAM_INT("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0);
// Search options.
PARAM_DOUBLE("tau", "The allowed rank-error in terms of the percentile of "
"the data.", "t", 5);
"the data.", "T", 5);
PARAM_DOUBLE("alpha", "The desired success probability.", "a", 0.95);
PARAM_FLAG("naive", "If true, sampling will be done without using a tree.",
"N");
+33 -10
View File
@@ -20,32 +20,55 @@ namespace mlpack {
namespace neighbor {
/**
* The AllkRANN class is the all-k-rank-approximate-nearest-neighbors method.
* It returns squared L2 distances (squared Euclidean distances) for each of the
* k rank-approximate nearest-neighbors. Squared distances are used because
* they are slightly faster than non-squared distances (they have one fewer call
* to sqrt()).
* The KRANN class is the k-rank-approximate-nearest-neighbors method. It
* returns L2 distances for each of the k rank-approximate nearest-neighbors.
*
* The approximation is controlled with two parameters (see allkrann_main.cpp)
* which can be specified at search time. So the tree building is done only once
* while the search can be performed multiple times with different approximation
* levels.
*/
typedef RASearch<> KRANN;
/**
* The KRAFN class is the k-rank-approximate-farthest-neighbors method. It
* returns L2 distances for each of the k rank-approximate farthest-neighbors.
*
* The approximation is controlled with two parameters (see allkrann_main.cpp)
* which can be specified at search time. So the tree building is done only once
* while the search can be performed multiple times with different approximation
* levels.
*/
typedef RASearch<FurthestNeighborSort> KRAFN;
/**
* @deprecated
* The AllkRANN class is the all-k-rank-approximate-nearest-neighbors method. It
* returns L2 distances for each of the k rank-approximate nearest-neighbors.
*
* The approximation is controlled with two parameters (see allkrann_main.cpp)
* which can be specified at search time. So the tree building is done only once
* while the search can be performed multiple times with different approximation
* levels.
*
* This typedef will be removed in mlpack 3.0.0; use the KRANN typedef instead.
*/
typedef RASearch<> AllkRANN;
/**
* @deprecated
* The AllkRAFN class is the all-k-rank-approximate-farthest-neighbors method.
* It returns squared L2 distances (squared Euclidean distances) for each of the
* k rank-approximate farthest-neighbors. Squared distances are used because
* they are slightly faster than non-squared distances (they have one fewer
* call to sqrt()).
* It returns L2 distances for each of the k rank-approximate
* farthest-neighbors.
*
* The approximation is controlled with two parameters (see allkrann_main.cpp)
* which can be specified at search time. So the tree building is done only once
* while the search can be performed multiple times with different approximation
* levels.
*
* This typedef will be removed in mlpack 3.0.0; use the KRANN typedef instead.
*/
typedef RASearch<FurthestNeighborSort> AllkRAFN;
typedef RASearch<> AllkRAFN;
} // namespace neighbor
} // namespace mlpack
@@ -21,9 +21,9 @@ PROGRAM_INFO("Softmax Regression", "This program performs softmax regression, "
"(-r), and if an intercept term is not desired in the model, the "
"--no_intercept (-N) can be specified."
"\n\n"
"The trained model can be saved to a file with the --output_model (-m) "
"The trained model can be saved to a file with the --output_model_file (-m) "
"option. If training is not desired, but only testing is, a model can be "
"loaded with the --input_model (-i) option. At the current time, a loaded "
"loaded with the --input_model_file (-i) option. At the current time, a loaded "
"model cannot be trained further, so specifying both -i and -t is not "
"allowed."
"\n\n"
@@ -80,10 +80,10 @@ void TestPredictAcc(const string& testFile,
// Build the softmax model given the parameters.
template<typename Model>
std::unique_ptr<Model> TrainSoftmax(const string& trainingFile,
const string& labelFile,
const string& inputModelFile,
const size_t maxIterations);
unique_ptr<Model> TrainSoftmax(const string& trainingFile,
const string& labelsFile,
const string& inputModelFile,
const size_t maxIterations);
int main(int argc, char** argv)
{
@@ -91,39 +91,39 @@ int main(int argc, char** argv)
CLI::ParseCommandLine(argc, argv);
const std::string trainingFile = CLI::GetParam<std::string>("training_file");
const std::string inputModelFile = CLI::GetParam<std::string>("input_model");
const string trainingFile = CLI::GetParam<string>("training_file");
const string labelsFile = CLI::GetParam<string>("labels_file");
const string inputModelFile = CLI::GetParam<string>("input_model_file");
const string outputModelFile = CLI::GetParam<string>("output_model_file");
const string testLabelsFile = CLI::GetParam<string>("test_labels");
const int maxIterations = CLI::GetParam<int>("max_iterations");
const string predictionsFile = CLI::GetParam<string>("predictions_file");
// One of inputFile and modelFile must be specified.
if (inputModelFile.empty() && trainingFile.empty())
Log::Fatal << "One of --input_model or --training_file must be specified."
if (!CLI::HasParam("input_model_file") && !CLI::HasParam("training_file"))
Log::Fatal << "One of --input_model_file or --training_file must be specified."
<< endl;
const std::string labelFile = CLI::GetParam<std::string>("labels_file");
if (!trainingFile.empty() && labelFile.empty())
if (CLI::HasParam("training_file") && CLI::HasParam("labels_file"))
Log::Fatal << "--labels_file must be specified with --training_file!"
<< endl;
const int maxIterations = CLI::GetParam<int>("max_iterations");
if (maxIterations < 0)
Log::Fatal << "Invalid value for maximum iterations (" << maxIterations
<< ")! Must be greater than or equal to 0." << endl;
const string outputModelFile = CLI::GetParam<string>("output_model");
const string testLabelsFile = CLI::GetParam<string>("test_labels");
const string predictionsFile = CLI::GetParam<string>("predictions_file");
// Make sure we have an output file of some sort.
if (outputModelFile.empty() && testLabelsFile.empty() &&
predictionsFile.empty())
Log::Warn << "None of --output_model, --test_labels, or --predictions_file "
<< "are set; no results from this program will be saved." << endl;
if (!CLI::HasParam("output_model_file") &&
!CLI::HasParam("test_labels") &&
!CLI::HasParam("predictions_file"))
Log::Warn << "None of --output_model_file, --test_labels, or "
<< "--predictions_file are set; no results from this program will be "
<< "saved." << endl;
using SM = regression::SoftmaxRegression<>;
std::unique_ptr<SM> sm = TrainSoftmax<SM>(trainingFile,
labelFile,
unique_ptr<SM> sm = TrainSoftmax<SM>(trainingFile,
labelsFile,
inputModelFile,
maxIterations);
@@ -132,11 +132,9 @@ int main(int argc, char** argv)
CLI::GetParam<string>("test_labels"),
sm->NumClasses(), *sm);
if (!outputModelFile.empty())
{
data::Save(CLI::GetParam<std::string>("output_model"),
if (CLI::HasParam("output_model_file"))
data::Save(CLI::GetParam<string>("output_model_file"),
"softmax_regression_model", *sm, true);
}
}
size_t CalculateNumberOfClasses(const size_t numClasses,
@@ -144,8 +142,8 @@ size_t CalculateNumberOfClasses(const size_t numClasses,
{
if (numClasses == 0)
{
const std::set<size_t> unique_labels(std::begin(trainLabels),
std::end(trainLabels));
const set<size_t> unique_labels(begin(trainLabels),
end(trainLabels));
return unique_labels.size();
}
else
@@ -203,12 +201,12 @@ void TestPredictAcc(const string& testFile,
if (testData.n_cols != testLabels.n_elem)
{
Log::Fatal << "Test data in --test_data has " << testData.n_cols
<< " points, but labels in --test_labels have " << testLabels.n_elem
<< " labels!" << endl;
<< " points, but labels in --test_labels have "
<< testLabels.n_elem << " labels!" << endl;
}
std::vector<size_t> bingoLabels(numClasses, 0);
std::vector<size_t> labelSize(numClasses, 0);
vector<size_t> bingoLabels(numClasses, 0);
vector<size_t> labelSize(numClasses, 0);
for (arma::uword i = 0; i != predictLabels.n_elem; ++i)
{
if (predictLabels(i) == testLabels(i))
@@ -234,16 +232,16 @@ void TestPredictAcc(const string& testFile,
}
template<typename Model>
std::unique_ptr<Model> TrainSoftmax(const string& trainingFile,
const string& labelFile,
const string& inputModelFile,
const size_t maxIterations)
unique_ptr<Model> TrainSoftmax(const string& trainingFile,
const string& labelsFile,
const string& inputModelFile,
const size_t maxIterations)
{
using namespace mlpack;
using SRF = regression::SoftmaxRegressionFunction;
std::unique_ptr<Model> sm;
unique_ptr<Model> sm;
if (!inputModelFile.empty())
{
sm.reset(new Model(0, 0, false));
@@ -258,7 +256,7 @@ std::unique_ptr<Model> TrainSoftmax(const string& trainingFile,
//load functions of mlpack do not works on windows, it will complain
//"[FATAL] Unable to detect type of 'softmax_data.txt'; incorrect extension?"
data::Load(trainingFile, trainData, true);
data::Load(labelFile, tmpTrainLabels, true);
data::Load(labelsFile, tmpTrainLabels, true);
trainLabels = tmpTrainLabels.row(0);
if (trainData.n_cols != trainLabels.n_elem)
+1 -1
View File
@@ -5,7 +5,6 @@ add_executable(mlpack_test
adaboost_test.cpp
adam_test.cpp
ada_delta_test.cpp
allkrann_search_test.cpp
arma_extend_test.cpp
aug_lagrangian_test.cpp
cf_test.cpp
@@ -30,6 +29,7 @@ add_executable(mlpack_test
kfn_test.cpp
kmeans_test.cpp
knn_test.cpp
krann_search_test.cpp
lars_test.cpp
lbfgs_test.cpp
lin_alg_test.cpp
@@ -22,9 +22,9 @@ using namespace mlpack::tree;
using namespace mlpack::metric;
using namespace mlpack::bound;
BOOST_AUTO_TEST_SUITE(AllkRANNTest);
BOOST_AUTO_TEST_SUITE(KRANNTest);
// Test the correctness and guarantees of AllkRANN when in naive mode.
// Test the correctness and guarantees of KRANN when in naive mode.
BOOST_AUTO_TEST_CASE(NaiveGuaranteeTest)
{
arma::Mat<size_t> neighbors;
@@ -562,8 +562,8 @@ BOOST_AUTO_TEST_CASE(MoveConstructorTest)
arma::mat dataset = arma::randu<arma::mat>(3, 200);
arma::mat copy(dataset);
AllkRANN moveknn(std::move(copy));
AllkRANN knn(dataset);
KRANN moveknn(std::move(copy));
KRANN knn(dataset);
BOOST_REQUIRE_EQUAL(copy.n_elem, 0);
BOOST_REQUIRE_EQUAL(moveknn.ReferenceSet().n_rows, 3);
@@ -590,7 +590,7 @@ BOOST_AUTO_TEST_CASE(MoveTrainTest)
arma::mat dataset = arma::randu<arma::mat>(3, 200);
// Do it in tree mode, and in naive mode.
AllkRANN knn;
KRANN knn;
knn.Train(std::move(dataset));
arma::mat distances;