Browse Source

update of null space methods

bodesheim 12 years ago
parent
commit
9fed4e2c71

+ 127 - 71
classifier/kernelclassifier/KCNullSpaceNovelty.cpp → classifier/kernelclassifier/KCNullSpace.cpp

@@ -1,6 +1,6 @@
 /** 
-* @file KCNullSpaceNovelty.cpp
-* @brief Novelty detection with kernel null space methods (Kernel Null Foley Sammon Transform - KNFST)
+* @file KCNullSpace.cpp
+* @brief Classification and novelty detection with kernel null space methods (Kernel Null Foley Sammon Transform - KNFST)
 * @author Paul Bodesheim
 * @date 26/11/2012
 
@@ -10,7 +10,7 @@
 
 #include "core/vector/Algorithms.h"
 
-#include "KCNullSpaceNovelty.h"
+#include "KCNullSpace.h"
 #include <limits>
 
 #undef DEBUG
@@ -19,7 +19,7 @@ using namespace NICE;
 using namespace std;
 using namespace OBJREC;
 
-KCNullSpaceNovelty::KCNullSpaceNovelty( const Config *conf, Kernel *kernelFunction, const string & section )
+KCNullSpace::KCNullSpace( const Config *conf, Kernel *kernelFunction, const string & section )
 	: KernelClassifier ( conf, kernelFunction )
 {
 	this->maxClassNo = 0;
@@ -27,7 +27,7 @@ KCNullSpaceNovelty::KCNullSpaceNovelty( const Config *conf, Kernel *kernelFuncti
 
 }
 
-KCNullSpaceNovelty::KCNullSpaceNovelty( const KCNullSpaceNovelty &vcova ): KernelClassifier(vcova)
+KCNullSpace::KCNullSpace( const KCNullSpace &vcova ): KernelClassifier(vcova)
 {
 
 	verbose = vcova.verbose;
@@ -35,8 +35,7 @@ KCNullSpaceNovelty::KCNullSpaceNovelty( const KCNullSpaceNovelty &vcova ): Kerne
         oneClassSetting = vcova.oneClassSetting;
         
         trainingSetStatistic.clear();
-        std::map<int,int>::iterator it;
-        for ( it = ( (std::map<int,int>)vcova.trainingSetStatistic ).begin(); it != vcova.trainingSetStatistic.end(); it++ )
+        for ( std::map<int,int>::const_iterator it = vcova.trainingSetStatistic.begin(); it != vcova.trainingSetStatistic.end(); it++ )
         {
           trainingSetStatistic.insert(pair<int,int>( (*it).first,(*it).second ));
         }
@@ -47,14 +46,14 @@ KCNullSpaceNovelty::KCNullSpaceNovelty( const KCNullSpaceNovelty &vcova ): Kerne
 	{
           for(int j = 0; j < (int)vcova.nullProjectionDirections.cols(); j++)
           {
-                nullProjectionDirections(i,j) = vcova.nullProjectionDirections(i,j);
+            nullProjectionDirections(i,j) = vcova.nullProjectionDirections(i,j);
           }          
 	}
 
         targetPoints.clear();
-        for(int i = 0; i < (int)vcova.targetPoints.size(); i++)
+        for( std::map<int,NICE::Vector>::const_iterator it = vcova.targetPoints.begin(); it != vcova.targetPoints.end(); it++ )
         {
-                targetPoints.push_back( NICE::Vector(vcova.targetPoints[i]) );
+          targetPoints.insert(pair<int,NICE::Vector>( (*it).first,(*it).second ));
         }
         
         eigenBasis.resize( vcova.eigenBasis.rows(),vcova.eigenBasis.cols() );
@@ -68,71 +67,77 @@ KCNullSpaceNovelty::KCNullSpaceNovelty( const KCNullSpaceNovelty &vcova ): Kerne
         }
 }
 
-KCNullSpaceNovelty::~KCNullSpaceNovelty()
+KCNullSpace::~KCNullSpace()
 {
 
 }
 
-void KCNullSpaceNovelty::teach ( KernelData *kernelData, const NICE::Vector & y )
+void KCNullSpace::teach ( KernelData *kernelData, const NICE::Vector & y )
 {
         NICE::Vector labels(y);
-	maxClassNo = (int)labels.Max();
+        int maxLabel( (int)labels.Max());
         
         /** check if we are in a one-class setting */
-        int minClassNo = (int)labels.Min();
-        if (maxClassNo == minClassNo)
+        int minLabel( (int)labels.Min());
+        if (maxLabel == minLabel)
         {
           oneClassSetting = true;
+          maxClassNo = 1;
           if (verbose)
-            std::cerr << "KCNullSpaceNovelty::teach: one-class setting" << std::endl;
-          computeTrainingSetStatistic(labels);
+            std::cerr << "KCNullSpace::teach: one-class setting" << std::endl;
           /** one-class setting: add a row and a column of zeros to the kernel matrix representing dot products with origin in kernel feature space*/
           kernelData->increase_size_by_One();
           kernelData->getKernelMatrix() (kernelData->getKernelMatrix().rows()-1, kernelData->getKernelMatrix().cols()-1) = 0.0;
-          labels.append(minClassNo+1);
+          labels.append(minLabel+1);
+          computeTrainingSetStatistic(labels);
+          
         }
         else
         {
           oneClassSetting = false;
           if (verbose)
-            std::cerr << "KCNullSpaceNovelty::teach: multi-class setting" << std::endl;          
+            std::cerr << "KCNullSpace::teach: multi-class setting" << std::endl;          
           computeTrainingSetStatistic(labels);
+          maxClassNo = trainingSetStatistic.size()-1; // number of classes, start counting at 0
         }
-
-        if (verbose)
-          std::cerr << "KCNullSpaceNovelty::teach: compute null projection directions..." << std::endl;   
+         
         computeNullProjectionDirections(kernelData,labels);
-        if (verbose)
-          std::cerr << "KCNullSpaceNovelty::teach: compute target points..." << std::endl;  
+ 
         computeTargetPoints(kernelData,labels);
+        
+        if (oneClassSetting)
+        {
+          /** remove the value that corresponds to the dot product with the origin in the kernel feature space, since this is always equal to zero */
+          nullProjectionDirections.deleteRow(nullProjectionDirections.rows()-1);
+        }
 }
 
-std::map<int,int> KCNullSpaceNovelty::getTrainingSetStatistic()
+std::map<int,int> * KCNullSpace::getTrainingSetStatistic()
 {
-  return trainingSetStatistic; 
+  return &trainingSetStatistic; 
 }
 
-NICE::Matrix KCNullSpaceNovelty::getNullProjectionDirections()
+NICE::Matrix KCNullSpace::getNullProjectionDirections()
 {
   return nullProjectionDirections;
 }
 
-NICE::VVector  KCNullSpaceNovelty::getTargetPoints()
+std::map<int,NICE::Vector> *  KCNullSpace::getTargetPoints()
 {
-  return targetPoints;
+  return &targetPoints;
 }
 
-int  KCNullSpaceNovelty::getNullSpaceDimension()
+int  KCNullSpace::getNullSpaceDimension()
 {
   return dimNullSpace;
 }
 
-bool  KCNullSpaceNovelty::isOneClass()
+bool  KCNullSpace::isOneClass()
 {
   return oneClassSetting;
 }
 
-void KCNullSpaceNovelty::computeTrainingSetStatistic(const NICE::Vector & y)
+void KCNullSpace::computeTrainingSetStatistic(const NICE::Vector & y)
 {
         trainingSetStatistic.clear();
         std::map<int,int>::iterator it;
@@ -150,8 +155,11 @@ void KCNullSpaceNovelty::computeTrainingSetStatistic(const NICE::Vector & y)
         }  
 }
 
-void KCNullSpaceNovelty::computeBasisUsingKernelPCA(const KernelData *kernelData)
+void KCNullSpace::computeBasisUsingKernelPCA(const KernelData *kernelData)
 {
+        if (verbose)
+          std::cerr << "KCNullSpace::computeBasisUsingKernelPCA: compute kernel PCA basis..." << std::endl;
+        
         NICE::Matrix K (kernelData->getKernelMatrix());
         
         /** let K represent dot products of zero mean data in kernel feature space */
@@ -160,8 +168,13 @@ void KCNullSpaceNovelty::computeBasisUsingKernelPCA(const KernelData *kernelData
         /** get eigenvectors and eigenvalues (descreasing order) of centered kernel matrix*/
         NICE::Matrix eigenVectors(K.rows(), K.cols(), 0.0);
         NICE::Vector eigenValues(K.rows(), 0.0);
+        K.addIdentity(1.0);
         eigenvectorvalues(K, eigenVectors, eigenValues);
-
+        eigenValues -= 1.0;
+//         NICE::GMCovariance gm(&K);
+//         NICE::EigValuesTRLAN ev;
+//         ev.getEigenvalues(gm, eigenValues, eigenVectors, K.rows());
+        
         /** only use eigenvectors of non-zero eigenvalues */
         int j(0);
         for (size_t i=0; i<K.rows(); i++)
@@ -187,21 +200,25 @@ void KCNullSpaceNovelty::computeBasisUsingKernelPCA(const KernelData *kernelData
         }
         
         eigenBasis = eigenVectors;
+        
+        if (verbose)
+          std::cerr << "KCNullSpace::computeBasisUsingKernelPCA: computation done" << std::endl;        
     
 }
     
-void KCNullSpaceNovelty::centerKernelMatrix(NICE::Matrix & kernelMatrix)
+void KCNullSpace::centerKernelMatrix(NICE::Matrix & kernelMatrix)
 {
         NICE::Matrix onesK (kernelMatrix.rows(), kernelMatrix.cols(), 1.0/kernelMatrix.rows());
         kernelMatrix = kernelMatrix - onesK*kernelMatrix - kernelMatrix*onesK + onesK*kernelMatrix*onesK;
 }
     
-void KCNullSpaceNovelty::computeNullProjectionDirections ( const KernelData *kernelData, const NICE::Vector & y )
+void KCNullSpace::computeNullProjectionDirections ( const KernelData *kernelData, const NICE::Vector & y )
 {
          
-        /** obtain Kernel PCA basis */
         if (verbose)
-          std::cerr << "KCNullSpaceNovelty::computeNullProjectionDirections: compute kernel PCA basis..." << std::endl;
+          std::cerr << "KCNullSpace::computeNullProjectionDirections: compute null projection directions..." << std::endl; 
+        
+        /** obtain Kernel PCA basis */
         computeBasisUsingKernelPCA(kernelData);      
         
         /** set matrix IM=(I-M) with I being the unit matrix and M being a matrix with all entries equal to 1/n where n is the number of training samples */
@@ -214,7 +231,7 @@ void KCNullSpaceNovelty::computeNullProjectionDirections ( const KernelData *ker
         for (size_t c=0; c<IL.cols(); c++)
         {
           /** if sample with index r is in the same class as sample with index c, then insert the value 1/numClassSamples */
-          for (size_t r=0; IL.rows(); r++)
+          for (size_t r=0; r<IL.rows(); r++)
           { 
             if ( y(r) == y(c) )
             {
@@ -234,7 +251,15 @@ void KCNullSpaceNovelty::computeNullProjectionDirections ( const KernelData *ker
         /** get eigenvectors and eigenvalues (descreasing order) of T */
         NICE::Matrix eigenVectors(T.rows(), T.cols(), 0.0);
         NICE::Vector eigenValues(T.rows(), 0.0);
+        T.addIdentity(1.0);
         eigenvectorvalues(T, eigenVectors, eigenValues);
+        eigenValues -= 1.0;
+//         NICE::GMCovariance gm(&T);
+//         NICE::EigValuesTRLAN ev;
+//         ev.getEigenvalues(gm, eigenValues, eigenVectors, T.rows());
+        
+        if (verbose)
+          std::cerr << "T: " << T.rows() << " x " << T.rows() << " nan: " << T.containsNaN()<< std::endl;
         
         /** only use eigenvectors of zero eigenvalues (null space!!!) but at least one eigenvector according to the smallest eigenvalue (therefore start at index i=T.rows()-2)*/
         for (int i=T.rows()-2; i>=0; i--)
@@ -248,13 +273,16 @@ void KCNullSpaceNovelty::computeNullProjectionDirections ( const KernelData *ker
         /** compute null projection directions */
         nullProjectionDirections = IM*eigenVectors;
         dimNullSpace = nullProjectionDirections.cols();
+        
         if (verbose)
-          std::cerr << "KCNullSpaceNovelty::computeNullProjectionDirections: computation done" << std::endl;
+          std::cerr << "KCNullSpace::computeNullProjectionDirections: computation done" << std::endl;
 }
 
-void KCNullSpaceNovelty::computeTargetPoints ( const KernelData *kernelData, const NICE::Vector & y )
+void KCNullSpace::computeTargetPoints ( const KernelData *kernelData, const NICE::Vector & y )
 {
-  
+  if (verbose)
+    std::cerr << "KCNullSpace::computeTargetPoints: compute target points..." << std::endl; 
+          
   targetPoints.clear();
   NICE::Vector targetPoint (dimNullSpace, 0.0);
   int classLabel(0);
@@ -277,21 +305,20 @@ void KCNullSpaceNovelty::computeTargetPoints ( const KernelData *kernelData, con
     targetPoint /= (*it).second;
     
     /** we only have one target point in an one-class setting */
-    targetPoints.push_back(targetPoint);
+    targetPoints.insert(pair<int,NICE::Vector>( classLabel,targetPoint));
     
   }
   else
   {
     
     /** create averaging vectors for each class, necessary to compute target points at the end of this method */
-    std::vector<NICE::Vector> averagingVectors;
+    std::map<int,NICE::Vector> averagingVectors;
     averagingVectors.clear();
     NICE::Vector averagingVector(y.size(),0.0);
     
-    /** insert one averaging vector and one target point vector for each class */
-    std::map<int,int>::iterator it;
+    /** insert one averaging vector  for each class */
     int numClassSamples(0);
-    for ( it = trainingSetStatistic.begin(); it != trainingSetStatistic.end(); it++ )
+    for ( std::map<int,int>::iterator it = trainingSetStatistic.begin(); it != trainingSetStatistic.end(); it++ )
     {
       
       /** create current averaging vector */
@@ -310,60 +337,87 @@ void KCNullSpaceNovelty::computeTargetPoints ( const KernelData *kernelData, con
       }
       
       /** insert averaging vector for current class*/
-      averagingVectors.push_back(averagingVector);
-      /** insert a null vector for the target point of the current class */
-      targetPoints.push_back(targetPoint);
+      averagingVectors.insert(pair<int,NICE::Vector>( classLabel,averagingVector));
     }
     
     /** compute target points using previously created averaging vectors: average for each class the projections of the class samples in the null space */
-    for ( size_t i = 0 ; i < targetPoints.size(); i++ )
+    for ( std::map<int,NICE::Vector>::iterator it = averagingVectors.begin(); it != averagingVectors.end(); it++ )
     {
-      targetPoints[i] = nullProjectionDirections.transpose() * kernelData->getKernelMatrix() * averagingVectors[i];
+       targetPoint = nullProjectionDirections.transpose() * kernelData->getKernelMatrix() * (*it).second;
+       targetPoints.insert(pair<int,NICE::Vector>( (*it).first,targetPoint));
     }    
     
   }
   
   if (verbose)
-    std::cerr << "KCNullSpaceNovelty::computeTargetPoints: computation done" << std::endl;
+    std::cerr << "KCNullSpace::computeTargetPoints: computation done" << std::endl;
   
 }
 
-ClassificationResult KCNullSpaceNovelty::classifyKernel ( const NICE::Vector & kernelVector, double kernelSelf ) const
+ClassificationResult KCNullSpace::classifyKernel ( const NICE::Vector & kernelVector, double kernelSelf ) const
 {
 	if ( targetPoints.size() <= 0 ) 
 		fthrow(Exception, "The classifier was not trained with training data (use teach(...))");
         
+        if (oneClassSetting)
+        {
+          return noveltyDetection ( kernelVector, kernelSelf );
+        }  
+        
         NICE::Vector projection(dimNullSpace,0.0);
         projection = nullProjectionDirections.transpose() * kernelVector;
         
-	FullVector scores ( trainingSetStatistic.size() );
-	scores.set(0);
+	FullVector scores ( maxClassNo+1 );
+	scores.set(- std::numeric_limits<double>::max());
         
-        std::map<int,int>::iterator it;
-        int iter(0);
-        for ( it = ( (std::map<int,int>)trainingSetStatistic ).begin(); it != trainingSetStatistic.end(); it++ )
+        int iter(0);     
+        for ( std::map<int,NICE::Vector>::const_iterator it = targetPoints.begin(); it != targetPoints.end(); it++ )
         {
-          scores[iter] = -(targetPoints[iter] - projection).normL2();
+          scores[iter] = 1.0-(it->second - projection).normL2();
           iter++;         
         }
         
 	ClassificationResult r ( scores.maxElement(), scores );
-
 	return r;
 }
 
-KCNullSpaceNovelty* KCNullSpaceNovelty::clone(void) const
+ClassificationResult KCNullSpace::noveltyDetection ( const NICE::Vector & kernelVector, double kernelSelf ) const
 {
-	KCNullSpaceNovelty *classifier = new KCNullSpaceNovelty( *this );
+        if ( targetPoints.size() <= 0 ) 
+                fthrow(Exception, "The classifier was not trained with training data (use teach(...))");
+               
+        NICE::Vector projection(dimNullSpace,0.0);
+        projection = nullProjectionDirections.transpose() * kernelVector;
+        
+        FullVector scores ( 2 );
+        scores.set(- std::numeric_limits<double>::max());
+        double tmp_score(0.0);
+        
+        for ( std::map<int,NICE::Vector>::const_iterator it = targetPoints.begin(); it != targetPoints.end(); it++ )
+        {
+          tmp_score = 1.0-(it->second - projection).normL2();
+          if (tmp_score > scores[1])
+          {
+            scores[1] = tmp_score;
+          }
+        }
+        
+        ClassificationResult r ( scores.maxElement(), scores );
+        return r;
+}
+
+KCNullSpace* KCNullSpace::clone(void) const
+{
+	KCNullSpace *classifier = new KCNullSpace( *this );
 	return classifier;
 }
 
-void KCNullSpaceNovelty::clear()
+void KCNullSpace::clear()
 {
 	//nothing to clear
 }
 
-void KCNullSpaceNovelty::restore(std::istream& ifs, int type)
+void KCNullSpace::restore(std::istream& ifs, int type)
 {
 	ifs.precision (numeric_limits<double>::digits10 + 1);
 	ifs >> maxClassNo;
@@ -390,14 +444,15 @@ void KCNullSpaceNovelty::restore(std::istream& ifs, int type)
         ifs >> k;
         for (int i=0; i<k; i++)
         {
+          ifs >> classLabel;
           ifs >> targetPoint;
-          targetPoints.push_back(targetPoint);
+          targetPoints.insert( pair<int,NICE::Vector>(classLabel,targetPoint) );
         }
         
 	KernelClassifier::restore(ifs,type);
 }
 
-void KCNullSpaceNovelty::store(std::ostream& ofs, int type) const
+void KCNullSpace::store(std::ostream& ofs, int type) const
 {
 	ofs.precision (numeric_limits<double>::digits10 + 1);
 	
@@ -408,8 +463,7 @@ void KCNullSpaceNovelty::store(std::ostream& ofs, int type) const
         ofs << eigenBasis << endl;
         
         ofs << trainingSetStatistic.size() << endl;
-        std::map<int,int>::iterator it;
-        for (it = ( (std::map<int,int>)trainingSetStatistic ).begin() ; it != trainingSetStatistic.end(); it++)
+        for (std::map<int,int>::const_iterator it = trainingSetStatistic.begin() ; it != trainingSetStatistic.end(); it++)
         {
           ofs << (*it).first << endl;
           ofs << (*it).second << endl;
@@ -418,9 +472,11 @@ void KCNullSpaceNovelty::store(std::ostream& ofs, int type) const
         ofs << nullProjectionDirections << endl;
         
         ofs << targetPoints.size() << endl;
-        for (size_t k=0; k<targetPoints.size(); k++)
+        for (std::map<int,NICE::Vector>::const_iterator it = targetPoints.begin() ; it != targetPoints.end(); it++)
         {
-          ofs << targetPoints[k] << endl;
+          
+          ofs << (*it).first << endl;
+          ofs << (*it).second << endl;
         }
 	
 	KernelClassifier::store(ofs,type);

+ 21 - 16
classifier/kernelclassifier/KCNullSpaceNovelty.h → classifier/kernelclassifier/KCNullSpace.h

@@ -1,27 +1,28 @@
 /**
-* @file KCNullSpaceNovelty.h
+* @file KCNullSpace.h
 * @author Paul Bodesheim
 * @date 26/11/2012
 
 */
-#ifndef _NICE_OBJREC_KCNULLSPACENOVELTYINCLUDE
-#define _NICE_OBJREC_KCNULLSPACENOVELTYINCLUDE
+#ifndef _NICE_OBJREC_KCNULLSPACEINCLUDE
+#define _NICE_OBJREC_KCNULLSPACEINCLUDE
 
 #include "vislearning/math/mathbase/FullVector.h"
 #include "vislearning/classifier/classifierbase/KernelClassifier.h"
 #include <vector>
 #include "core/vector/VVector.h"
 #include "core/vector/Eigen.h"
+// #include "core/algebra/EigValuesTRLAN.h" 
 
 namespace OBJREC
 {
 
-/** @class KCNullSpaceNovelty
- * Novelty detection with kernel null space methods (Kernel Null Foley Sammon Transform - KNFST)
+/** @class KCNullSpace
+ * Classification and novelty detection with kernel null space methods (Kernel Null Foley Sammon Transform - KNFST)
  *
  * @author Paul Bodesheim
  */
-class KCNullSpaceNovelty : public KernelClassifier
+class KCNullSpace : public KernelClassifier
 {
 
   protected:
@@ -38,8 +39,8 @@ class KCNullSpaceNovelty : public KernelClassifier
     /** null projection directions in columns of a matrix */
     NICE::Matrix nullProjectionDirections;
     
-    /** target points in the null space represented as NICE::Vector's within a std::vector */
-    NICE::VVector targetPoints; 
+    /** target points in the null space represented as NICE::Vector's associated with the corresponding class label in this map */
+    std::map<int, NICE::Vector> targetPoints; 
     
     /** dimension of the null space */
     int dimNullSpace;
@@ -65,16 +66,16 @@ class KCNullSpaceNovelty : public KernelClassifier
   public:
     
     /** simplest constructor */
-    KCNullSpaceNovelty() {};
+    KCNullSpace() {};
 
     /** simple constructor */
-    KCNullSpaceNovelty ( const NICE::Config *conf, Kernel *kernelFunction = NULL, const std::string & section = "KCNullSpaceNovelty" );
+    KCNullSpace ( const NICE::Config *conf, Kernel *kernelFunction = NULL, const std::string & section = "KCNullSpace" );
 
     /** copy constructor */
-    KCNullSpaceNovelty ( const KCNullSpaceNovelty &vcova );
+    KCNullSpace ( const KCNullSpace &vcova );
 
     /** simple destructor */
-    virtual ~KCNullSpaceNovelty();
+    virtual ~KCNullSpace();
 
     /** teach the classifier with a kernel matrix and the corresponding class labels @param y ! */
     void teach ( KernelData *kernelData, const NICE::Vector & y );
@@ -83,15 +84,19 @@ class KCNullSpaceNovelty : public KernelClassifier
     /** classify an example by using its kernel values with the training set,
      be careful with the order in @param kernelVector */
     ClassificationResult classifyKernel ( const NICE::Vector & kernelVector, double kernelSelf ) const;
+    
+    /** classify an example concerning novelty (binary decision) by using its kernel values with the training set,
+     be careful with the order in @param kernelVector */
+    ClassificationResult noveltyDetection ( const NICE::Vector & kernelVector, double kernelSelf ) const;
  
     /** return class labels and corresponding number of class samples */
-    std::map<int,int> getTrainingSetStatistic();
+    std::map<int,int> * getTrainingSetStatistic();
     
     /** return null projection directions in columns of a matrix */
     NICE::Matrix  getNullProjectionDirections();
 
-    /** return target points as NICE::Vector's within a std::vector */
-    NICE::VVector getTargetPoints();
+    /** return target points as NICE::Vector's associated with the corresponding class labels in a map */
+    std::map<int, NICE::Vector> * getTargetPoints();
     
     /** true if it is a one-class setting */
     bool isOneClass();
@@ -104,7 +109,7 @@ class KCNullSpaceNovelty : public KernelClassifier
     void clear();
 
     /** clone this object */
-    virtual KCNullSpaceNovelty *clone ( void ) const;
+    virtual KCNullSpace *clone ( void ) const;
     
 };
 

+ 458 - 0
classifier/kernelclassifier/progs/testNullSpace.cpp

@@ -0,0 +1,458 @@
+/** 
+* @file testNullSpace.cpp
+* @brief test function for class KCNullSpace
+* @author Paul Bodesheim
+* @date 28-11-2012 (dd-mm-yyyy)
+*/
+
+#include <ctime>
+#include <time.h>
+
+#include "core/basics/Config.h"
+#include "core/basics/Timer.h"
+#include "core/vector/Algorithms.h"
+#include "core/vector/SparseVectorT.h"
+
+#include "vislearning/classifier/kernelclassifier/KCNullSpace.h"
+#include "vislearning/math/kernels/KernelData.h"
+#include "vislearning/cbaselib/ClassificationResults.h"
+#include "vislearning/baselib/ProgressBar.h"
+
+#include "core/matlabAccess/MatFileIO.h"
+#include "vislearning/matlabAccessHighLevel/ImageNetData.h"
+
+// #include <iostream>
+// #include <fstream>
+
+using namespace std;
+using namespace NICE;
+using namespace OBJREC;
+
+// --------------- THE KERNEL FUNCTION ( exponential kernel with euclidian distance ) ----------------------
+double measureDistance ( const NICE::SparseVector & a, const NICE::SparseVector & b, const double & sigma = 2.0)
+{
+  double inner_sum(0.0);
+
+  double d;      
+  
+  //new version, where we needed on average 0.001707 s for each test sample
+  NICE::SparseVector::const_iterator aIt = a.begin();
+  NICE::SparseVector::const_iterator bIt = b.begin();
+   
+  //compute the euclidian distance between both feature vectores (given as SparseVectors)
+  while ( (aIt != a.end()) && (bIt != b.end()) )
+  {
+    if (aIt->first == bIt->first)
+    {
+      d = ( aIt->second - bIt->second );      
+      inner_sum += d * d;
+      aIt++;
+      bIt++;
+    }
+    else if ( aIt->first < bIt->first)
+    {
+      inner_sum += aIt->second * aIt->second;
+      aIt++;      
+    }
+    else
+    {
+      inner_sum += bIt->second * bIt->second;
+      bIt++;       
+    }
+  }
+  
+  //compute remaining values, if b reached the end but not a
+  while (aIt != a.end())
+  {
+    inner_sum += aIt->second * aIt->second;
+    aIt++; 
+  }
+  //compute remaining values, if a reached the end but not b
+  while (bIt != b.end())
+  {
+    inner_sum += bIt->second * bIt->second;
+    bIt++; 
+  }  
+
+  //normalization of the exponent
+  inner_sum /= (2.0*sigma*sigma);
+  
+  //finally, compute the RBF-kernel score (RBF = radial basis function)
+  return exp(-inner_sum);
+}
+
+// --------------- THE KERNEL FUNCTION ( HIK ) ----------------------
+double minimumDistance ( const NICE::SparseVector & a, const NICE::SparseVector & b )
+{
+  double inner_sum(0.0);
+  
+  NICE::SparseVector::const_iterator aIt = a.begin();
+  NICE::SparseVector::const_iterator bIt = b.begin();
+  
+  //compute the minimum distance between both feature vectores (given as SparseVectors)
+  while ( (aIt != a.end()) && (bIt != b.end()) )
+  {
+    if (aIt->first == bIt->first)
+    {
+      inner_sum += std::min( aIt->second , bIt->second );
+      aIt++;
+      bIt++;
+    }
+    else if ( aIt->first < bIt->first)
+    {
+      aIt++;      
+    }
+    else
+    {
+      bIt++;       
+    }
+  }
+  
+  return inner_sum;
+  
+}
+
+/** 
+    test the basic functionality of fast-hik hyperparameter optimization 
+*/
+int main (int argc, char **argv)
+{   
+  std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+
+  Config conf ( argc, argv );
+  string resultsfile = conf.gS("main", "results", "results.txt" );
+  int nrOfExamplesPerClass = conf.gI("main", "nrOfExamplesPerClass", 100);
+  nrOfExamplesPerClass = std::min(nrOfExamplesPerClass, 100); // we do not have more than 100 examples per class
+  int maxKnownClass = conf.gI("KCNullSpace", "maxKnownClass", 5);
+  int OCCsingleClassLabel = conf.gI("KCNullSpace", "OCCsingleClassLabel", 1);
+  bool testVerbose = conf.gB("KCNullSpace", "verbose", false);
+  
+  std::cerr << "conf verbose: " << testVerbose << std::endl;
+  
+  // -------- read ImageNet data --------------  
+  std::vector<SparseVector> trainingData;
+  NICE::Vector y;
+  NICE::Vector yTest;
+  
+  std::cerr << "Reading ImageNet data ..." << std::endl;
+  bool imageNetLocal = conf.gB("main", "imageNetLocal" , false);
+  string imageNetPath;
+  if (imageNetLocal)
+    imageNetPath = "/users2/rodner/data/imagenet/devkit-1.0/";
+  else
+    imageNetPath = "/home/dbv/bilder/imagenet/devkit-1.0/";
+
+  ImageNetData imageNetTrain ( imageNetPath + "demo/" );
+
+  imageNetTrain.preloadData( "train", "training" );
+  imageNetTrain.normalizeData("L1");
+  trainingData = imageNetTrain.getPreloadedData();
+  y = imageNetTrain.getPreloadedLabels();
+  
+  std::cerr << "Reading of training data finished" << std::endl;
+  std::cerr << "trainingData.size(): " << trainingData.size() << std::endl;
+  std::cerr << "y.size(): " << y.size() << std::endl;
+  
+  std::cerr << "Reading ImageNet test data files (takes some seconds)..." << std::endl;
+  ImageNetData imageNetTest ( imageNetPath + "demo/" );
+  imageNetTest.preloadData ( "val", "testing" );
+  imageNetTest.normalizeData("L1");
+  imageNetTest.loadExternalLabels ( imageNetPath + "data/ILSVRC2010_validation_ground_truth.txt" );  
+  yTest = imageNetTest.getPreloadedLabels();
+
+  // ---------- SELECT TRAINING SET FOR MULTICLASS NOVELTY DETECTION AND COMPUTE KERNEL MATRIX ------------------------
+  NICE::Vector knownClassLabels(maxKnownClass,0.0);
+  for (int k=1; k<=maxKnownClass; k++)
+    knownClassLabels(k-1) = k;
+  
+  std::vector<SparseVector> currentTrainingData;
+  currentTrainingData.clear();
+  NICE::Vector currentTrainingLabels(nrOfExamplesPerClass*knownClassLabels.size(),0);
+  
+  int kk(0);
+  for (size_t i = 0; i < y.size(); i++)
+  {
+    for (size_t j=0; j<knownClassLabels.size(); j++)
+    {
+      if ( y[i] == knownClassLabels[j] )
+      {
+        currentTrainingLabels(kk) = knownClassLabels[j];
+        currentTrainingData.push_back(trainingData[i]);
+        kk++;
+        break;
+      }  
+    }
+    
+  }
+  
+  Timer tTrain;
+  tTrain.start();
+    
+  //compute the kernel matrix
+  NICE::Matrix kernelMatrix(nrOfExamplesPerClass*knownClassLabels.size(), nrOfExamplesPerClass*knownClassLabels.size(), 0.0);
+  double kernelScore(0.0);
+  
+  for (size_t i = 0; i < kernelMatrix.rows(); i++)
+  {
+    for (size_t j = i; j < kernelMatrix.cols(); j++)
+    {
+      kernelScore = minimumDistance(currentTrainingData[i],currentTrainingData[j]);
+      kernelMatrix(i,j) = kernelScore;
+        
+      if (i != j)
+          kernelMatrix(j,i) = kernelScore;
+    }
+  }    
+  
+  KernelData kernelData( &conf, kernelMatrix, "Kernel", false );
+  KCNullSpace knfst( &conf);
+  
+  // train the model
+  knfst.teach(&kernelData, currentTrainingLabels);
+  
+  tTrain.stop();
+  std::cerr << "Time used for training " << ": " << tTrain.getLast() << std::endl;  
+  
+  // some outputs of training
+  std::cerr << "training set statistic: " << std::endl;
+  for (std::map<int,int>::iterator it = knfst.getTrainingSetStatistic()->begin(); it != knfst.getTrainingSetStatistic()->end(); it++)
+  {
+    std::cerr << "class label: " << (*it).first << "  number of class samples: " << (*it).second << std::endl;
+  }
+  std::cerr << "one-class setting?: " << knfst.isOneClass() << std::endl;
+  std::cerr << "null space dimension: "<< knfst.getNullSpaceDimension() << std::endl;
+  std::cerr << "target points: " << std::endl;
+  for (std::map<int,NICE::Vector>::iterator it = knfst.getTargetPoints()->begin(); it != knfst.getTargetPoints()->end(); it++)
+    std::cerr << (*it).second << std::endl;    
+       
+  std::cerr << "training done - now perform the evaluation" << std::endl;
+
+  // --------- TESTING MULTICLASS NOVELTY DETECTION ------------------------------
+   
+  std::cerr << "Multi-class novelty detection... with " << imageNetTest.getNumPreloadedExamples() << " examples" << std::endl;
+    
+  ClassificationResults results;
+
+  ProgressBar pb;
+  Timer tTest;
+  tTest.start();    
+
+  for ( uint i = 0 ; i < (uint)imageNetTest.getNumPreloadedExamples(); i++ )
+  {
+    if ( (i % 100)==0)
+      pb.update ( imageNetTest.getNumPreloadedExamples()/100 );
+
+    const SparseVector & svec = imageNetTest.getPreloadedExample ( i );
+     
+    // compute (self) similarities
+    double kernelSelf (minimumDistance(svec,svec) );
+    NICE::Vector kernelVector (nrOfExamplesPerClass*knownClassLabels.size(), 0.0);
+      
+    for (uint j = 0; j < nrOfExamplesPerClass*knownClassLabels.size(); j++)
+    {
+      kernelVector[j] = minimumDistance(currentTrainingData[j],svec);
+    }     
+      
+    ClassificationResult r;      
+    r = knfst.noveltyDetection( kernelVector, kernelSelf);  
+      
+    // set ground truth label
+    r.classno_groundtruth = 0;
+    for (size_t j=0; j<knownClassLabels.size(); j++)
+    {
+      if ( yTest[i] == knownClassLabels[j] )
+      {
+        r.classno_groundtruth = 1;
+        break;
+      }
+    }
+
+    // remember the results for the evaluation lateron
+    results.push_back ( r );
+  }
+    
+  tTest.stop();
+  std::cerr << "Time used for evaluation: " << tTest.getLast() << std::endl;       
+    
+  double timeForSingleExample(0.0);
+  timeForSingleExample = tTest.getLast()/imageNetTest.getNumPreloadedExamples();
+  std::cerr.precision(10);
+  std::cerr << "time used for evaluation of single elements: " << timeForSingleExample << std::endl;      
+  
+  // run the AUC-evaluation
+  double perfvalue( 0.0 );   
+  perfvalue = results.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
+
+  std::cerr << " novelty detection performance: " << perfvalue << std::endl;
+  
+  // --------- TESTING MULTICLASS CLASSIFICATION ------------------------------
+  results.clear();
+  tTest.start();    
+    
+  for ( uint i = 0 ; i < (uint)imageNetTest.getNumPreloadedExamples(); i++ )
+  {
+    // only use samples of known classes
+    if ( yTest[i] > maxKnownClass) 
+    {
+      continue;
+    }
+    
+    const SparseVector & svec = imageNetTest.getPreloadedExample ( i );
+     
+    // compute (self) similarities
+    double kernelSelf (minimumDistance(svec,svec) );
+    NICE::Vector kernelVector (nrOfExamplesPerClass*knownClassLabels.size(), 0.0);
+      
+    for (uint j = 0; j < nrOfExamplesPerClass*knownClassLabels.size(); j++)
+    {
+      kernelVector[j] = minimumDistance(currentTrainingData[j],svec);
+    }     
+      
+    ClassificationResult r;      
+    r = knfst.classifyKernel( kernelVector, kernelSelf);  
+      
+    // set ground truth label
+    for (uint j=0; j < knownClassLabels.size(); j++)
+    {
+      if (yTest[i] == knownClassLabels[j])
+      {
+        r.classno_groundtruth = j;
+        break;
+      }
+    }
+    // remember the results for the evaluation lateron
+    results.push_back ( r );
+  }
+    
+  tTest.stop();
+  std::cerr << "Time used for evaluation: " << tTest.getLast() << std::endl;       
+    
+  timeForSingleExample = tTest.getLast()/imageNetTest.getNumPreloadedExamples();
+  std::cerr.precision(10);
+  std::cerr << "time used for evaluation of single elements: " << timeForSingleExample << std::endl;      
+  
+  // run the AUC-evaluation
+  perfvalue = results.getAverageRecognitionRate();
+
+  std::cerr << " classification performance: " << perfvalue << std::endl; 
+  
+  // ---------- SELECT TRAINING SET FOR ONECLASS CLASSIFICATION AND COMPUTE KERNEL MATRIX ------------------------ 
+  currentTrainingData.clear();
+  currentTrainingLabels.clear();
+  
+  for (size_t i = 0; i < y.size(); i++)
+  {
+    if ( y[i] == OCCsingleClassLabel )
+    {
+      currentTrainingLabels.append(OCCsingleClassLabel);
+      currentTrainingData.push_back(trainingData[i]);
+    }  
+  }
+      
+  tTrain.start();
+    
+  //compute the kernel matrix
+  NICE::Matrix kernelMatrixOCC(currentTrainingData.size(), currentTrainingData.size(), 0.0);
+  
+  std::cerr << "OCC Kernel Matrix: " << kernelMatrixOCC.rows() << " x " << kernelMatrixOCC.cols() << std::endl;
+  
+  for (size_t i = 0; i < kernelMatrixOCC.rows(); i++)
+  {
+    for (size_t j = i; j < kernelMatrixOCC.cols(); j++)
+    {
+      kernelScore = minimumDistance(currentTrainingData[i],currentTrainingData[j]);
+      kernelMatrixOCC(i,j) = kernelScore;
+        
+      if (i != j)
+          kernelMatrixOCC(j,i) = kernelScore;
+    }
+  }    
+  
+  filebuf fb;
+  fb.open("/home/bodesheim/experiments/kernelMatrixOCC.txt",ios::out);
+  ostream os (&fb);
+  os << kernelMatrixOCC;
+  fb.close();
+  
+  KernelData kernelDataOCC( &conf, kernelMatrixOCC, "Kernel", false );
+  
+  // train the model
+  std::cerr << "Train OCC model... " << std::endl;  
+  knfst.teach(&kernelDataOCC, currentTrainingLabels);
+  
+  tTrain.stop();
+  std::cerr << "Time used for training " << ": " << tTrain.getLast() << std::endl;  
+  
+  // some outputs of training
+  std::cerr << "training set statistic: " << std::endl;
+  for (std::map<int,int>::iterator itt = knfst.getTrainingSetStatistic()->begin(); itt != knfst.getTrainingSetStatistic()->end(); itt++)
+  {
+    std::cerr << "class label: " << (*itt).first << "  number of class samples: " << (*itt).second << std::endl;
+  }
+  std::cerr << "one-class setting?: " << knfst.isOneClass() << std::endl;
+  std::cerr << "null space dimension: "<< knfst.getNullSpaceDimension() << std::endl;
+  std::cerr << "target points: " << std::endl;
+  for (std::map<int,NICE::Vector>::const_iterator it = knfst.getTargetPoints()->begin(); it != knfst.getTargetPoints()->end(); it++)
+    std::cerr << (*it).second << std::endl;    
+       
+  std::cerr << "training done - now perform the evaluation" << std::endl;
+
+  // --------- TESTING OCC ------------------------------
+   
+  std::cerr << "OCC... with " << imageNetTest.getNumPreloadedExamples() << " examples" << std::endl;
+    
+  results.clear();
+     
+  tTest.start();    
+  ProgressBar pb3;
+  
+  std::cerr << "start for loop" << std::endl;
+    
+  for ( uint i = 0 ; i < (uint)imageNetTest.getNumPreloadedExamples(); i++ )
+  {
+    if ( (i % 100)==0)
+      pb3.update ( imageNetTest.getNumPreloadedExamples()/100 );
+
+    const SparseVector & svec = imageNetTest.getPreloadedExample ( i );
+     
+    //compute (self) similarities
+    double kernelSelf (minimumDistance(svec,svec) );
+    NICE::Vector kernelVector (currentTrainingData.size(), 0.0);
+      
+    for (uint j = 0; j < currentTrainingData.size(); j++)
+    {
+      kernelVector[j] = minimumDistance(currentTrainingData[j],svec);
+    }     
+      
+    ClassificationResult r;
+    r = knfst.noveltyDetection( kernelVector, kernelSelf);  
+      
+    // set ground truth label
+    r.classno_groundtruth = 0;
+    if ( yTest[i] == OCCsingleClassLabel )
+    {
+      r.classno_groundtruth = 1;
+    }
+    else
+    {
+      r.classno_groundtruth = 0;
+    }
+
+    //remember the results for the evaluation lateron
+    results.push_back ( r );
+  }
+    
+  tTest.stop();
+  std::cerr << "Time used for evaluation: " << tTest.getLast() << std::endl;       
+    
+  double timeForSingleExampleOCC = tTest.getLast()/imageNetTest.getNumPreloadedExamples();
+  std::cerr.precision(10);
+  std::cerr << "time used for evaluation of single elements: " << timeForSingleExampleOCC << std::endl;      
+  
+  // run the AUC-evaluation
+  double perfvalueOCC = results.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
+
+  std::cerr << " occ performance: " << perfvalueOCC << std::endl;
+  
+  return 0;
+}

+ 0 - 285
progs/testNullSpaceNovelty.cpp

@@ -1,285 +0,0 @@
-/** 
-* @file testNullSpaceNovelty.cpp
-* @brief test function for class KCNullSpaceNovelty
-* @author Paul Bodesheim
-* @date 28-11-2012 (dd-mm-yyyy)
-*/
-
-#include <ctime>
-#include <time.h>
-#include <iostream>
-
-#ifdef NICE_USELIB_MATIO
-
-#include "core/basics/Config.h"
-#include "core/basics/Timer.h"
-#include "core/vector/Algorithms.h"
-#include "core/vector/SparseVectorT.h"
-
-#include "vislearning/classifier/kernelclassifier/KCNullSpaceNovelty.h"
-#include "vislearning/math/kernels/KernelData.h"
-#include "vislearning/cbaselib/ClassificationResults.h"
-#include "vislearning/baselib/ProgressBar.h"
-
-#include "core/matlabAccess/MatFileIO.h"
-#include "vislearning/matlabAccessHighLevel/ImageNetData.h"
-
-using namespace std;
-using namespace NICE;
-using namespace OBJREC;
-
-// --------------- THE KERNEL FUNCTION ( exponential kernel with euclidian distance ) ----------------------
-double measureDistance ( const NICE::SparseVector & a, const NICE::SparseVector & b, const double & sigma = 2.0)
-{
-  double inner_sum(0.0);
-
-  double d;      
-  
-  //new version, where we needed on average 0.001707 s for each test sample
-  NICE::SparseVector::const_iterator aIt = a.begin();
-  NICE::SparseVector::const_iterator bIt = b.begin();
-   
-  //compute the euclidian distance between both feature vectores (given as SparseVectors)
-  while ( (aIt != a.end()) && (bIt != b.end()) )
-  {
-    if (aIt->first == bIt->first)
-    {
-      d = ( aIt->second - bIt->second );      
-      inner_sum += d * d;
-      aIt++;
-      bIt++;
-    }
-    else if ( aIt->first < bIt->first)
-    {
-      inner_sum += aIt->second * aIt->second;
-      aIt++;      
-    }
-    else
-    {
-      inner_sum += bIt->second * bIt->second;
-      bIt++;       
-    }
-  }
-  
-  //compute remaining values, if b reached the end but not a
-  while (aIt != a.end())
-  {
-    inner_sum += aIt->second * aIt->second;
-    aIt++; 
-  }
-  //compute remaining values, if a reached the end but not b
-  while (bIt != b.end())
-  {
-    inner_sum += bIt->second * bIt->second;
-    bIt++; 
-  }  
-
-  //normalization of the exponent
-  inner_sum /= (2.0*sigma*sigma);
-  
-  //finally, compute the RBF-kernel score (RBF = radial basis function)
-  return exp(-inner_sum);
-}
-
-// --------------- THE KERNEL FUNCTION ( HIK ) ----------------------
-double minimumDistance ( const NICE::SparseVector & a, const NICE::SparseVector & b )
-{
-  double inner_sum(0.0);
-  
-  NICE::SparseVector::const_iterator aIt = a.begin();
-  NICE::SparseVector::const_iterator bIt = b.begin();
-  
-  //compute the minimum distance between both feature vectores (given as SparseVectors)
-  while ( (aIt != a.end()) && (bIt != b.end()) )
-  {
-    if (aIt->first == bIt->first)
-    {
-      inner_sum += std::min( aIt->second , bIt->second );
-      aIt++;
-      bIt++;
-    }
-    else if ( aIt->first < bIt->first)
-    {
-      aIt++;      
-    }
-    else
-    {
-      bIt++;       
-    }
-  }
-  
-  return inner_sum;
-  
-}
-
-/** 
-    test the basic functionality of fast-hik hyperparameter optimization 
-*/
-int main (int argc, char **argv)
-{   
-  std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
-
-  Config conf ( argc, argv );
-  string resultsfile = conf.gS("main", "results", "results.txt" );
-  int nrOfExamplesPerClass = conf.gI("main", "nrOfExamplesPerClass", 100);
-  nrOfExamplesPerClass = std::min(nrOfExamplesPerClass, 100); // we do not have more than 100 examples per class
-    
-  // -------- read ImageNet data --------------  
-  std::vector<SparseVector> trainingData;
-  NICE::Vector y;
-  
-  std::cerr << "Reading ImageNet data ..." << std::endl;
-  bool imageNetLocal = conf.gB("main", "imageNetLocal" , false);
-  string imageNetPath;
-  if (imageNetLocal)
-    imageNetPath = "/users2/rodner/data/imagenet/devkit-1.0/";
-  else
-    imageNetPath = "/home/dbv/bilder/imagenet/devkit-1.0/";
-
-  ImageNetData imageNetTrain ( imageNetPath + "demo/" );
-
-  imageNetTrain.preloadData( "train", "training" );
-  trainingData = imageNetTrain.getPreloadedData();
-  y = imageNetTrain.getPreloadedLabels();
-    
-  std::cerr << "Reading of training data finished" << std::endl;
-  std::cerr << "trainingData.size(): " << trainingData.size() << std::endl;
-  std::cerr << "y.size(): " << y.size() << std::endl;
-  
-  std::cerr << "Reading ImageNet test data files (takes some seconds)..." << std::endl;
-  ImageNetData imageNetTest ( imageNetPath + "demo/" );
-  imageNetTest.preloadData ( "val", "testing" );
-  imageNetTest.loadExternalLabels ( imageNetPath + "data/ILSVRC2010_validation_ground_truth.txt" );  
-  
-  // -------- select training set -------------
-  NICE::Vector knownClassLabels(5,0.0);
-  for (int k=1; k<6; k++)
-    knownClassLabels(k-1) = k;
-  
-  std::vector<SparseVector> currentTrainingData;
-  currentTrainingData.clear();
-  NICE::Vector currentTrainingLabels(nrOfExamplesPerClass*knownClassLabels.size(),0);
-  
-  int k(0);
-  for (size_t i = 0; i < y.size(); i++)
-  {
-    for (size_t j=0; j<knownClassLabels.size(); j++)
-    {
-      if ( y[i] == knownClassLabels[j] )
-      {
-        currentTrainingLabels(k) = knownClassLabels[j];
-        currentTrainingData.push_back(trainingData[i]);
-        k++;
-        break;
-      }  
-    }
-    
-  }
-  
-  Timer tTrain;
-  tTrain.start();
-    
-  //compute the kernel matrix
-  NICE::Matrix kernelMatrix(nrOfExamplesPerClass*knownClassLabels.size(), nrOfExamplesPerClass*knownClassLabels.size(), 0.0);
-  double kernelScore(0.0);
-  int cl(0);
-  
-  for (size_t i = 0; i < kernelMatrix.rows(); i++)
-  {
-    for (size_t j = i; j < kernelMatrix.cols(); j++)
-    {
-      kernelScore = minimumDistance(currentTrainingData[i],currentTrainingData[j]);
-      kernelMatrix(i-cl*100,j-cl*100) = kernelScore;
-        
-      if (i != j)
-          kernelMatrix(j-cl*100,i-cl*100) = kernelScore;
-    }
-  }    
-  
-  KernelData kernelData( &conf, kernelMatrix, "Kernel", false );
-  KCNullSpaceNovelty knfst( &conf);
-  
-  knfst.teach(&kernelData, currentTrainingLabels);
-  
-  tTrain.stop();
-  std::cerr << "Time used for training " << cl << ": " << tTrain.getLast() << std::endl;  
-  
-  std::cerr << "training set statistic: " << std::endl;
-  std::map<int,int>::iterator itt;
-  for (itt = ( (std::map<int,int>) knfst.getTrainingSetStatistic() ).begin(); itt != knfst.getTrainingSetStatistic().end(); itt++)
-    std::cerr << (*itt).first << "  " << (*itt).second << std::endl;
-  std::cerr << "one-class setting?: " << knfst.isOneClass() << std::endl;
-  std::cerr << "null space dimension: "<< knfst.getNullSpaceDimension() << std::endl;
-  std::cerr << "target points: " << std::endl;
-  for (size_t k=0; k<knfst.getTargetPoints().size(); k++)
-    std::cerr << knfst.getTargetPoints()[k] << std::endl;    
-       
-  std::cerr << "training done - now perform the evaluation" << std::endl;
-
-  // ------------------------------ TESTING ------------------------------
-   
-  std::cerr << "Classification step ... with " << imageNetTest.getNumPreloadedExamples() << " examples" << std::endl;
-    
-  ClassificationResults results;
-     
-  ProgressBar pb;
-  Timer tTest;
-  tTest.start();    
-    
-  for ( uint i = 0 ; i < (uint)imageNetTest.getNumPreloadedExamples(); i++ )
-  {
-    pb.update ( imageNetTest.getNumPreloadedExamples() );
-
-    const SparseVector & svec = imageNetTest.getPreloadedExample ( i );
-     
-    //compute (self) similarities
-    double kernelSelf (minimumDistance(svec,svec) );
-    NICE::Vector kernelVector (nrOfExamplesPerClass, 0.0);
-      
-    for (int j = 0; j < nrOfExamplesPerClass; j++)
-    {
-      kernelVector[j] = minimumDistance(currentTrainingData[j],svec);
-    }     
-      
-    ClassificationResult r;      
-    r = knfst.classifyKernel( kernelVector, kernelSelf);  
-      
-    // set ground truth label
-    r.classno_groundtruth = 0;
-    for (size_t j=0; j<knownClassLabels.size(); j++)
-    {
-      if ( ((int)imageNetTest.getPreloadedLabel ( i )) == knownClassLabels[j] )
-      {
-        r.classno_groundtruth = 1;
-        break;
-      }
-    }
-
-    //remember the results for the evaluation lateron
-    results.push_back ( r );
-  }
-    
-  tTest.stop();
-  std::cerr << "Time used for evaluation: " << tTest.getLast() << std::endl;       
-    
-  double timeForSingleExample(0.0);
-  timeForSingleExample = tTest.getLast()/imageNetTest.getNumPreloadedExamples();
-  std::cerr.precision(10);
-  std::cerr << "time used for evaluation single elements: " << timeForSingleExample << std::endl;      
-
-  // run the AUC-evaluation
-  double perfvalue( 0.0 );   
-  perfvalue = results.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
-
-  std::cerr << " novelty detection performance: " << perfvalue << std::endl;
-  
-  return 0;
-}
-
-#else
-int main (int argc, char **argv)
-{
-  std::cerr << "MatIO library is missing in your system - this program will have no effect. " << std::endl;
-}
-
-#endif