[mlpack-git] master: Add a model for FastMKS, to be used by the command-line program for serialization. (48b4706)
gitdub at big.cc.gt.atl.ga.us
gitdub at big.cc.gt.atl.ga.us
Tue Dec 22 18:34:45 EST 2015
Repository : https://github.com/mlpack/mlpack
On branch : master
Link : https://github.com/mlpack/mlpack/compare/eb41f4bc27b484c347acc006255104e2f8cc4eef...977afbec0648056124dcb206e0bf972a161d9b51
>---------------------------------------------------------------
commit 48b470615a8f4106839c5449fbf89294ee529861
Author: ryan <ryan at ratml.org>
Date: Tue Dec 22 18:23:26 2015 -0500
Add a model for FastMKS, to be used by the command-line program for serialization.
>---------------------------------------------------------------
48b470615a8f4106839c5449fbf89294ee529861
src/mlpack/methods/fastmks/CMakeLists.txt | 3 +
src/mlpack/methods/fastmks/fastmks_model.cpp | 203 ++++++++++++++++++++
src/mlpack/methods/fastmks/fastmks_model.hpp | 135 ++++++++++++++
src/mlpack/methods/fastmks/fastmks_model_impl.hpp | 215 ++++++++++++++++++++++
4 files changed, 556 insertions(+)
diff --git a/src/mlpack/methods/fastmks/CMakeLists.txt b/src/mlpack/methods/fastmks/CMakeLists.txt
index fac46b6..2472e9b 100644
--- a/src/mlpack/methods/fastmks/CMakeLists.txt
+++ b/src/mlpack/methods/fastmks/CMakeLists.txt
@@ -3,6 +3,9 @@
set(SOURCES
fastmks.hpp
fastmks_impl.hpp
+ fastmks_model.hpp
+ fastmks_model_impl.hpp
+ fastmks_model.cpp
fastmks_rules.hpp
fastmks_rules_impl.hpp
)
diff --git a/src/mlpack/methods/fastmks/fastmks_model.cpp b/src/mlpack/methods/fastmks/fastmks_model.cpp
new file mode 100644
index 0000000..d4c85c2
--- /dev/null
+++ b/src/mlpack/methods/fastmks/fastmks_model.cpp
@@ -0,0 +1,203 @@
+/**
+ * @file fastmks_model.cpp
+ * @author Ryan Curtin
+ *
+ * Implementation of non-templatized functions of FastMKSModel.
+ */
+#include "fastmks_model.hpp"
+
+namespace mlpack {
+namespace fastmks {
+
+FastMKSModel::FastMKSModel(const int kernelType) :
+ kernelType(kernelType),
+ linear(NULL),
+ polynomial(NULL),
+ cosine(NULL),
+ gaussian(NULL),
+ epan(NULL),
+ triangular(NULL),
+ hyptan(NULL)
+{
+ // Nothing to do.
+}
+
+FastMKSModel::~FastMKSModel()
+{
+ // Clean memory.
+ if (linear)
+ delete linear;
+ if (polynomial)
+ delete polynomial;
+ if (cosine)
+ delete cosine;
+ if (gaussian)
+ delete gaussian;
+ if (epan)
+ delete epan;
+ if (triangular)
+ delete triangular;
+ if (hyptan)
+ delete hyptan;
+}
+
+bool FastMKSModel::Naive() const
+{
+ switch (kernelType)
+ {
+ case LINEAR_KERNEL:
+ return linear->Naive();
+ case POLYNOMIAL_KERNEL:
+ return polynomial->Naive();
+ case COSINE_DISTANCE:
+ return cosine->Naive();
+ case GAUSSIAN_KERNEL:
+ return gaussian->Naive();
+ case EPANECHNIKOV_KERNEL:
+ return epan->Naive();
+ case TRIANGULAR_KERNEL:
+ return triangular->Naive();
+ case HYPTAN_KERNEL:
+ return hyptan->Naive();
+ }
+
+ throw std::runtime_error("invalid model type");
+}
+
+bool& FastMKSModel::Naive()
+{
+ switch (kernelType)
+ {
+ case LINEAR_KERNEL:
+ return linear->Naive();
+ case POLYNOMIAL_KERNEL:
+ return polynomial->Naive();
+ case COSINE_DISTANCE:
+ return cosine->Naive();
+ case GAUSSIAN_KERNEL:
+ return gaussian->Naive();
+ case EPANECHNIKOV_KERNEL:
+ return epan->Naive();
+ case TRIANGULAR_KERNEL:
+ return triangular->Naive();
+ case HYPTAN_KERNEL:
+ return hyptan->Naive();
+ }
+
+ throw std::runtime_error("invalid model type");
+}
+
+bool FastMKSModel::SingleMode() const
+{
+ switch (kernelType)
+ {
+ case LINEAR_KERNEL:
+ return linear->SingleMode();
+ case POLYNOMIAL_KERNEL:
+ return polynomial->SingleMode();
+ case COSINE_DISTANCE:
+ return cosine->SingleMode();
+ case GAUSSIAN_KERNEL:
+ return gaussian->SingleMode();
+ case EPANECHNIKOV_KERNEL:
+ return epan->SingleMode();
+ case TRIANGULAR_KERNEL:
+ return triangular->SingleMode();
+ case HYPTAN_KERNEL:
+ return hyptan->SingleMode();
+ }
+
+ throw std::runtime_error("invalid model type");
+}
+
+bool& FastMKSModel::SingleMode()
+{
+ switch (kernelType)
+ {
+ case LINEAR_KERNEL:
+ return linear->SingleMode();
+ case POLYNOMIAL_KERNEL:
+ return polynomial->SingleMode();
+ case COSINE_DISTANCE:
+ return cosine->SingleMode();
+ case GAUSSIAN_KERNEL:
+ return gaussian->SingleMode();
+ case EPANECHNIKOV_KERNEL:
+ return epan->SingleMode();
+ case TRIANGULAR_KERNEL:
+ return triangular->SingleMode();
+ case HYPTAN_KERNEL:
+ return hyptan->SingleMode();
+ }
+
+ throw std::runtime_error("invalid model type");
+}
+
+void FastMKSModel::Search(const arma::mat& querySet,
+ const size_t k,
+ arma::Mat<size_t>& indices,
+ arma::mat& kernels,
+ const double base)
+{
+ switch (kernelType)
+ {
+ case LINEAR_KERNEL:
+ Search(*linear, querySet, k, indices, kernels, base);
+ break;
+ case POLYNOMIAL_KERNEL:
+ Search(*polynomial, querySet, k, indices, kernels, base);
+ break;
+ case COSINE_DISTANCE:
+ Search(*cosine, querySet, k, indices, kernels, base);
+ break;
+ case GAUSSIAN_KERNEL:
+ Search(*gaussian, querySet, k, indices, kernels, base);
+ break;
+ case EPANECHNIKOV_KERNEL:
+ Search(*epan, querySet, k, indices, kernels, base);
+ break;
+ case TRIANGULAR_KERNEL:
+ Search(*triangular, querySet, k, indices, kernels, base);
+ break;
+ case HYPTAN_KERNEL:
+ Search(*hyptan, querySet, k, indices, kernels, base);
+ break;
+ default:
+ throw std::runtime_error("invalid model type");
+ }
+}
+
+void FastMKSModel::Search(const size_t k,
+ arma::Mat<size_t>& indices,
+ arma::mat& kernels)
+{
+ switch (kernelType)
+ {
+ case LINEAR_KERNEL:
+ linear->Search(k, indices, kernels);
+ break;
+ case POLYNOMIAL_KERNEL:
+ polynomial->Search(k, indices, kernels);
+ break;
+ case COSINE_DISTANCE:
+ cosine->Search(k, indices, kernels);
+ break;
+ case GAUSSIAN_KERNEL:
+ gaussian->Search(k, indices, kernels);
+ break;
+ case EPANECHNIKOV_KERNEL:
+ epan->Search(k, indices, kernels);
+ break;
+ case TRIANGULAR_KERNEL:
+ triangular->Search(k, indices, kernels);
+ break;
+ case HYPTAN_KERNEL:
+ hyptan->Search(k, indices, kernels);
+ break;
+ default:
+ throw std::invalid_argument("invalid model type");
+ }
+}
+
+} // namespace fastmks
+} // namespace mlpack
diff --git a/src/mlpack/methods/fastmks/fastmks_model.hpp b/src/mlpack/methods/fastmks/fastmks_model.hpp
new file mode 100644
index 0000000..4289d4b
--- /dev/null
+++ b/src/mlpack/methods/fastmks/fastmks_model.hpp
@@ -0,0 +1,135 @@
+/**
+ * @file fastmks_model.hpp
+ * @author Ryan Curtin
+ *
+ * A utility struct to contain all the possible FastMKS models.
+ */
+#ifndef __MLPACK_METHODS_FASTMKS_FASTMKS_MODEL_HPP
+#define __MLPACK_METHODS_FASTMKS_FASTMKS_MODEL_HPP
+
+#include <mlpack/core.hpp>
+#include "fastmks.hpp"
+
+namespace mlpack {
+namespace fastmks {
+
+//! A utility struct to contain all the possible FastMKS models, for use by the
+//! mlpack_fastmks program.
+class FastMKSModel
+{
+ public:
+ //! A list of all the kernels we support.
+ enum KernelTypes
+ {
+ LINEAR_KERNEL,
+ POLYNOMIAL_KERNEL,
+ COSINE_DISTANCE,
+ GAUSSIAN_KERNEL,
+ EPANECHNIKOV_KERNEL,
+ TRIANGULAR_KERNEL,
+ HYPTAN_KERNEL
+ };
+
+ /**
+ * Create the FastMKSModel with the given kernel type.
+ */
+ FastMKSModel(const int kernelType = LINEAR_KERNEL);
+
+ /**
+ * Clean memory.
+ */
+ ~FastMKSModel();
+
+ /**
+ * Build the model on the given reference set. Make sure kernelType is equal
+ * to the correct entry in KernelTypes for the given KernelType class!
+ */
+ template<typename KernelType>
+ void BuildModel(const arma::mat& referenceData,
+ KernelType& kernel,
+ const bool singleMode,
+ const bool naive,
+ const double base);
+
+ //! Get whether or not naive search is used.
+ bool Naive() const;
+ //! Set whether or not naive search is used.
+ bool& Naive();
+
+ //! Get whether or not single-tree search is used.
+ bool SingleMode() const;
+ //! Set whether or not single-tree search is used.
+ bool& SingleMode();
+
+ /**
+ * Search with a different query set.
+ *
+ * @param querySet Set to search with.
+ * @param k Number of max-kernel candidates to search for.
+ * @param indices A matrix in which to store the indices of max-kernel
+ * candidates.
+ * @param kernels A matrix in which to store the max-kernel candidate kernel
+ * values.
+ * @param base Base to use for cover tree building (if in dual-tree search
+ * mode).
+ */
+ void Search(const arma::mat& querySet,
+ const size_t k,
+ arma::Mat<size_t>& indices,
+ arma::mat& kernels,
+ const double base);
+
+ /**
+ * Search with the reference set as the query set.
+ *
+ * @param k Number of max-kernel candidates to search for.
+ * @param indices A matrix in which to store the indices of max-kernel
+ * candidates.
+ * @param kernels A matrix in which to store the max-kernel candidate kernel
+ * values.
+ */
+ void Search(const size_t k,
+ arma::Mat<size_t>& indices,
+ arma::mat& kernels);
+
+ /**
+ * Serialize the model.
+ */
+ template<typename Archive>
+ void Serialize(Archive& ar, const unsigned int /* version */);
+
+ private:
+ //! The type of kernel we are using.
+ int kernelType;
+
+ //! This will only be non-NULL if this is the type of kernel we are using.
+ FastMKS<kernel::LinearKernel>* linear;
+ //! This will only be non-NULL if this is the type of kernel we are using.
+ FastMKS<kernel::PolynomialKernel>* polynomial;
+ //! This will only be non-NULL if this is the type of kernel we are using.
+ FastMKS<kernel::CosineDistance>* cosine;
+ //! This will only be non-NULL if this is the type of kernel we are using.
+ FastMKS<kernel::GaussianKernel>* gaussian;
+ //! This will only be non-NULL if this is the type of kernel we are using.
+ FastMKS<kernel::EpanechnikovKernel>* epan;
+ //! This will only be non-NULL if this is the type of kernel we are using.
+ FastMKS<kernel::TriangularKernel>* triangular;
+ //! This will only be non-NULL if this is the type of kernel we are using.
+ FastMKS<kernel::HyperbolicTangentKernel>* hyptan;
+
+ //! Build a query tree and execute the search.
+ template<typename FastMKSType>
+ void Search(FastMKSType& f,
+ const arma::mat& querySet,
+ const size_t k,
+ arma::Mat<size_t>& indices,
+ arma::mat& kernels,
+ const double base);
+};
+
+} // namespace fastmks
+} // namespace mlpack
+
+#include "fastmks_model_impl.hpp"
+
+#endif
diff --git a/src/mlpack/methods/fastmks/fastmks_model_impl.hpp b/src/mlpack/methods/fastmks/fastmks_model_impl.hpp
new file mode 100644
index 0000000..b9c02e5
--- /dev/null
+++ b/src/mlpack/methods/fastmks/fastmks_model_impl.hpp
@@ -0,0 +1,215 @@
+/**
+ * @file fastmks_model_impl.hpp
+ * @author Ryan Curtin
+ *
+ * Implementation of templated functions of FastMKSModel.
+ */
+#ifndef __MLPACK_METHODS_FASTMKS_FASTMKS_MODEL_IMPL_HPP
+#define __MLPACK_METHODS_FASTMKS_FASTMKS_MODEL_IMPL_HPP
+
+#include "fastmks_model.hpp"
+
+namespace mlpack {
+namespace fastmks {
+
+//! This is called when the KernelType is the same as the model.
+template<typename KernelType>
+void BuildFastMKSModel(FastMKS<KernelType>& f,
+ KernelType& k,
+ const arma::mat& referenceData,
+ const double base)
+{
+ // Do we need to build the tree?
+ if (f.Naive())
+ {
+ f.Train(referenceData, k);
+ }
+ else
+ {
+ // Create the tree with the specified base.
+ Timer::Start("tree_building");
+ metric::IPMetric<KernelType> metric(k);
+ typename FastMKS<KernelType>::Tree* tree =
+ new typename FastMKS<KernelType>::Tree(referenceData, metric, base);
+ Timer::Stop("tree_building");
+
+ f.Train(tree);
+ }
+}
+
+//! This is only called when something goes wrong.
+template<typename KernelType,
+ typename FastMKSType>
+void BuildFastMKSModel(FastMKSType& f,
+ KernelType& k,
+ const arma::mat& referenceData,
+ const double base)
+{
+ throw std::invalid_argument("FastMKSModel::BuildModel(): given kernel type is"
+ " not equal to kernel type of the model!");
+}
+
+template<typename KernelType>
+void FastMKSModel::BuildModel(const arma::mat& referenceData,
+ KernelType& kernel,
+ const bool singleMode,
+ const bool naive,
+ const double base)
+{
+ // Clean memory if necessary.
+ if (linear)
+ delete linear;
+ if (polynomial)
+ delete polynomial;
+ if (cosine)
+ delete cosine;
+ if (gaussian)
+ delete gaussian;
+ if (epan)
+ delete epan;
+ if (triangular)
+ delete triangular;
+ if (hyptan)
+ delete hyptan;
+
+ linear = NULL;
+ polynomial = NULL;
+ cosine = NULL;
+ gaussian = NULL;
+ epan = NULL;
+ triangular = NULL;
+ hyptan = NULL;
+
+ // Instantiate the right model.
+ switch (kernelType)
+ {
+ case LINEAR_KERNEL:
+ linear = new FastMKS<kernel::LinearKernel>(singleMode, naive);
+ BuildFastMKSModel(*linear, kernel, referenceData, base);
+ break;
+
+ case POLYNOMIAL_KERNEL:
+ polynomial = new FastMKS<kernel::PolynomialKernel>(singleMode, naive);
+ BuildFastMKSModel(*polynomial, kernel, referenceData, base);
+ break;
+
+ case COSINE_DISTANCE:
+ cosine = new FastMKS<kernel::CosineDistance>(singleMode, naive);
+ BuildFastMKSModel(*cosine, kernel, referenceData, base);
+ break;
+
+ case GAUSSIAN_KERNEL:
+ gaussian = new FastMKS<kernel::GaussianKernel>(singleMode, naive);
+ BuildFastMKSModel(*gaussian, kernel, referenceData, base);
+ break;
+
+ case EPANECHNIKOV_KERNEL:
+ epan = new FastMKS<kernel::EpanechnikovKernel>(singleMode, naive);
+ BuildFastMKSModel(*epan, kernel, referenceData, base);
+ break;
+
+ case TRIANGULAR_KERNEL:
+ triangular = new FastMKS<kernel::TriangularKernel>(singleMode, naive);
+ BuildFastMKSModel(*triangular, kernel, referenceData, base);
+ break;
+
+ case HYPTAN_KERNEL:
+ hyptan = new FastMKS<kernel::HyperbolicTangentKernel>(singleMode, naive);
+ BuildFastMKSModel(*hyptan, kernel, referenceData, base);
+ break;
+ }
+}
+
+template<typename Archive>
+void FastMKSModel::Serialize(Archive& ar, const unsigned int /* version */)
+{
+ using data::CreateNVP;
+
+ ar & CreateNVP(kernelType, "kernelType");
+
+ if (Archive::is_loading::value)
+ {
+ // Clean memory.
+ if (linear)
+ delete linear;
+ if (polynomial)
+ delete polynomial;
+ if (cosine)
+ delete cosine;
+ if (gaussian)
+ delete gaussian;
+ if (epan)
+ delete epan;
+ if (triangular)
+ delete triangular;
+ if (hyptan)
+ delete hyptan;
+
+ linear = NULL;
+ polynomial = NULL;
+ cosine = NULL;
+ gaussian = NULL;
+ epan = NULL;
+ triangular = NULL;
+ hyptan = NULL;
+ }
+
+ // Serialize the correct model.
+ switch (kernelType)
+ {
+ case LINEAR_KERNEL:
+ ar & CreateNVP(linear, "linear_fastmks");
+ break;
+
+ case POLYNOMIAL_KERNEL:
+ ar & CreateNVP(polynomial, "polynomial_fastmks");
+ break;
+
+ case COSINE_DISTANCE:
+ ar & CreateNVP(cosine, "cosine_fastmks");
+ break;
+
+ case GAUSSIAN_KERNEL:
+ ar & CreateNVP(gaussian, "gaussian_fastmks");
+ break;
+
+ case EPANECHNIKOV_KERNEL:
+ ar & CreateNVP(epan, "epan_fastmks");
+ break;
+
+ case TRIANGULAR_KERNEL:
+ ar & CreateNVP(triangular, "triangular_fastmks");
+ break;
+
+ case HYPTAN_KERNEL:
+ ar & CreateNVP(hyptan, "hyptan_fastmks");
+ break;
+ }
+}
+
+template<typename FastMKSType>
+void FastMKSModel::Search(FastMKSType& f,
+ const arma::mat& querySet,
+ const size_t k,
+ arma::Mat<size_t>& indices,
+ arma::mat& kernels,
+ const double base)
+{
+ if (f.Naive() || f.SingleMode())
+ {
+ f.Search(querySet, k, indices, kernels);
+ }
+ else
+ {
+ Timer::Start("tree_building");
+ typename FastMKSType::Tree queryTree(querySet, base);
+ Timer::Stop("tree_building");
+
+ f.Search(&queryTree, k, indices, kernels);
+ }
+}
+
+} // namespace fastmks
+} // namespace mlpack
+
+#endif
More information about the mlpack-git
mailing list