[mlpack-svn] r10749 - mlpack/trunk/src/mlpack/methods/nca

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Tue Dec 13 06:31:00 EST 2011


Author: rcurtin
Date: 2011-12-13 06:31:00 -0500 (Tue, 13 Dec 2011)
New Revision: 10749

Modified:
   mlpack/trunk/src/mlpack/methods/nca/nca.hpp
   mlpack/trunk/src/mlpack/methods/nca/nca_impl.hpp
   mlpack/trunk/src/mlpack/methods/nca/nca_softmax_error_function.hpp
   mlpack/trunk/src/mlpack/methods/nca/nca_softmax_error_function_impl.hpp
Log:
Abstract-ize matrix type used for NCA datasets.  The covariance matrix should
not be sparse, though.


Modified: mlpack/trunk/src/mlpack/methods/nca/nca.hpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/nca/nca.hpp	2011-12-13 11:30:22 UTC (rev 10748)
+++ mlpack/trunk/src/mlpack/methods/nca/nca.hpp	2011-12-13 11:31:00 UTC (rev 10749)
@@ -33,8 +33,11 @@
  *   title = {{Neighbourhood Components Analysis}},
  *   year = {2004}
  * }
+ *
+ * @tparam MetricType Distance metric to use.
+ * @tparam MatType Type of matrix (arma::mat or arma::spmat).
  */
-template<typename Kernel>
+template<typename MetricType, typename MatType = arma::mat>
 class NCA
 {
  public:
@@ -44,7 +47,7 @@
    *
    * @param dataset Input dataset.
    */
-  NCA(const arma::mat& dataset, const arma::uvec& labels);
+  NCA(const MatType& dataset, const arma::uvec& labels);
 
   /**
    * Perform Neighborhood Components Analysis.  The output distance learning
@@ -52,10 +55,10 @@
    *
    * @param output_matrix Covariance matrix of Mahalanobis distance.
    */
-  void LearnDistance(arma::mat& output_matrix);
+  void LearnDistance(MatType& output_matrix);
 
  private:
-  const arma::mat& dataset_;
+  const MatType& dataset_;
   const arma::uvec& labels_;
 };
 

Modified: mlpack/trunk/src/mlpack/methods/nca/nca_impl.hpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/nca/nca_impl.hpp	2011-12-13 11:30:22 UTC (rev 10748)
+++ mlpack/trunk/src/mlpack/methods/nca/nca_impl.hpp	2011-12-13 11:31:00 UTC (rev 10749)
@@ -18,19 +18,25 @@
 namespace nca {
 
 // Just set the internal matrix reference.
-template<typename Kernel>
-NCA<Kernel>::NCA(const arma::mat& dataset, const arma::uvec& labels) :
-    dataset_(dataset), labels_(labels) { /* nothing to do */ }
+template<typename MetricType, typename MatType>
+NCA<MetricType, MatType>::NCA(const MatType& dataset,
+                              const arma::uvec& labels) :
+    dataset_(dataset),
+    labels_(labels)
+{
+  /* nothing to do */
+}
 
-template<typename Kernel>
-void NCA<Kernel>::LearnDistance(arma::mat& output_matrix)
+template<typename MetricType, typename MatType>
+void NCA<MetricType, MatType>::LearnDistance(MatType& output_matrix)
 {
-  output_matrix = arma::eye<arma::mat>(dataset_.n_rows, dataset_.n_rows);
+  output_matrix = arma::eye<MatType>(dataset_.n_rows, dataset_.n_rows);
 
-  SoftmaxErrorFunction<Kernel> error_func(dataset_, labels_);
+  SoftmaxErrorFunction<MetricType> error_func(dataset_, labels_);
 
   // We will use the L-BFGS optimizer to optimize the stretching matrix.
-  optimization::L_BFGS<SoftmaxErrorFunction<Kernel> > lbfgs(error_func, 10);
+  optimization::L_BFGS<SoftmaxErrorFunction<MetricType, MatType> >
+      lbfgs(error_func, 10);
 
   lbfgs.Optimize(0, output_matrix);
 }

Modified: mlpack/trunk/src/mlpack/methods/nca/nca_softmax_error_function.hpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/nca/nca_softmax_error_function.hpp	2011-12-13 11:30:22 UTC (rev 10748)
+++ mlpack/trunk/src/mlpack/methods/nca/nca_softmax_error_function.hpp	2011-12-13 11:31:00 UTC (rev 10749)
@@ -24,27 +24,30 @@
  * where x_n represents a point and A is the current scaling matrix.
  *
  * This class is more flexible than the original paper, allowing an arbitrary
- * kernel function to be used, meaning that the Mahalanobis distance is not the
+ * metric function to be used, meaning that the Mahalanobis distance is not the
  * only allowed way to run NCA.  However, the Mahalanobis distance is probably
  * the best way to use this.
+ *
+ * @tparam MetricType Type of metric to be used.
+ * @tparam MatType Type of matrix (arma::mat or arma::spmat).
  */
-template<typename Kernel>
+template<typename MetricType, typename MatType = arma::mat>
 class SoftmaxErrorFunction
 {
  public:
   /**
-   * Initialize with the given kernel; useful when the kernel has some state to
-   * store, which is set elsewhere.  If no kernel is given, an empty kernel is
+   * Initialize with the given metric; useful when the metric has some state to
+   * store, which is set elsewhere.  If no metric is given, an empty metric is
    * used; this way, you can call the constructor with no arguments.  A
    * reference to the dataset we will be optimizing over is also required.
    *
    * @param dataset Matrix containing the dataset.
    * @param labels Vector of class labels for each point in the dataset.
-   * @param kernel Instantiated kernel (optional).
+   * @param metric Instantiated metric (optional).
    */
-  SoftmaxErrorFunction(const arma::mat& dataset,
+  SoftmaxErrorFunction(const MatType& dataset,
                        const arma::uvec& labels,
-                       Kernel kernel = Kernel());
+                       MetricType metric = MetricType());
 
   /**
    * Evaluate the softmax function for the given covariance matrix.
@@ -68,13 +71,13 @@
   const arma::mat GetInitialPoint() const;
 
  private:
-  const arma::mat& dataset_;
+  const MatType& dataset_;
   const arma::uvec& labels_;
 
-  Kernel kernel_;
+  MetricType metric_;
 
   arma::mat last_coordinates_;
-  arma::mat stretched_dataset_;
+  MatType stretched_dataset_;
   arma::vec p_; // Holds calculated p_i.
   arma::vec denominators_; // Holds denominators for calculation of p_ij.
 

Modified: mlpack/trunk/src/mlpack/methods/nca/nca_softmax_error_function_impl.hpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/nca/nca_softmax_error_function_impl.hpp	2011-12-13 11:30:22 UTC (rev 10748)
+++ mlpack/trunk/src/mlpack/methods/nca/nca_softmax_error_function_impl.hpp	2011-12-13 11:31:00 UTC (rev 10749)
@@ -13,18 +13,24 @@
 namespace mlpack {
 namespace nca {
 
-// Initialize with the given kernel.
-template<typename Kernel>
-SoftmaxErrorFunction<Kernel>::SoftmaxErrorFunction(const arma::mat& dataset,
-                                                   const arma::uvec& labels,
-                                                   Kernel kernel) :
-  dataset_(dataset), labels_(labels), kernel_(kernel),
-  last_coordinates_(dataset.n_rows, dataset.n_rows),
-  precalculated_(false)
-{ /* nothing to do */ }
+// Initialize with the given metric.
+template<typename MetricType, typename MatType>
+SoftmaxErrorFunction<MetricType, MatType>::SoftmaxErrorFunction(
+    const MatType& dataset,
+    const arma::uvec& labels,
+    MetricType metric) :
+    dataset_(dataset),
+    labels_(labels),
+    metric_(metric),
+    last_coordinates_(dataset.n_rows, dataset.n_rows),
+    precalculated_(false)
+{
+  /* nothing to do */
+}
 
-template<typename Kernel>
-double SoftmaxErrorFunction<Kernel>::Evaluate(const arma::mat& coordinates)
+template<typename MetricType, typename MatType>
+double SoftmaxErrorFunction<MetricType, MatType>::Evaluate(
+    const arma::mat& coordinates)
 {
   // Calculate the denominators and numerators, if necessary.
   Precalculate(coordinates);
@@ -33,9 +39,10 @@
                     // minimizes, not maximizes.
 };
 
-template<typename Kernel>
-void SoftmaxErrorFunction<Kernel>::Gradient(const arma::mat& coordinates,
-                                            arma::mat& gradient)
+template<typename MetricType, typename MatType>
+void SoftmaxErrorFunction<MetricType, MatType>::Gradient(
+    const arma::mat& coordinates,
+    arma::mat& gradient)
 {
   // Calculate the denominators and numerators, if necessary.
   Precalculate(coordinates);
@@ -59,8 +66,8 @@
     for (size_t k = (i + 1); k < stretched_dataset_.n_cols; k++)
     {
       // Calculate p_ik and p_ki first.
-      double eval = exp(-kernel_.Evaluate(stretched_dataset_.unsafe_col(i),
-                                          stretched_dataset_.unsafe_col(k)));
+      double eval = exp(-metric_.Evaluate(stretched_dataset_.col(i),
+                                          stretched_dataset_.col(k)));
       double p_ik = 0, p_ki = 0;
       p_ik = eval / denominators_(i);
       p_ki = eval / denominators_(k);
@@ -80,14 +87,16 @@
   gradient = -2 * coordinates * sum;
 }
 
-template<typename Kernel>
-const arma::mat SoftmaxErrorFunction<Kernel>::GetInitialPoint() const
+template<typename MetricType, typename MatType>
+const arma::mat SoftmaxErrorFunction<MetricType, MatType>::GetInitialPoint()
+    const
 {
   return arma::eye<arma::mat>(dataset_.n_rows, dataset_.n_rows);
 }
 
-template<typename Kernel>
-void SoftmaxErrorFunction<Kernel>::Precalculate(const arma::mat& coordinates)
+template<typename MetricType, typename MatType>
+void SoftmaxErrorFunction<MetricType, MatType>::Precalculate(
+    const arma::mat& coordinates)
 {
   // Make sure the calculation is necessary.
   if ((accu(coordinates == last_coordinates_) == coordinates.n_elem) &&
@@ -111,8 +120,8 @@
     for (size_t j = (i + 1); j < stretched_dataset_.n_cols; j++)
     {
       // Evaluate exp(-K(x_i, x_j)).
-      double eval = exp(-kernel_.Evaluate(stretched_dataset_.unsafe_col(i),
-                                          stretched_dataset_.unsafe_col(j)));
+      double eval = exp(-metric_.Evaluate(stretched_dataset_.col(i),
+                                          stretched_dataset_.col(j)));
 
       // Add this to the denominators of both i and j: p_ij = p_ji.
       denominators_[i] += eval;




More information about the mlpack-svn mailing list