testLinsolvers.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /**
  2. * @file testImageNetBinary.cpp
  3. * @brief perform ImageNet tests with binary classification
  4. * @author Erik Rodner
  5. * @date 01/04/2012
  6. */
  7. #include "core/basics/Config.h"
  8. #ifdef NICE_USELIB_MATIO
  9. #include "core/algebra/IterativeLinearSolver.h"
  10. #include "core/algebra/PartialGenericMatrix.h"
  11. #include "core/algebra/GBCDSolver.h"
  12. #include "core/algebra/ILSConjugateGradients.h"
  13. #include <core/matlabAccess/MatFileIO.h>
  14. #include "vislearning/cbaselib/ClassificationResults.h"
  15. #include "vislearning/baselib/ProgressBar.h"
  16. #include <vislearning/matlabAccessHighLevel/ImageNetData.h>
  17. #include <gp-hik-core/kernels/IntersectionKernelFunction.h>
  18. #include <gp-hik-core/tools.h>
  19. #include <gp-hik-core/GMHIKernel.h>
  20. using namespace std;
  21. using namespace NICE;
  22. using namespace OBJREC;
  23. void selectExamples ( const Config *conf, const Vector & y, map<int, int> & examples, Vector & yb )
  24. {
  25. int positiveClass = conf->gI("main", "positive_class");
  26. map< int, set<int> > mysets;
  27. int n = y.size();
  28. set<int> positives;
  29. set<int> negatives;
  30. for ( uint i = 0 ; i < n; i++ )
  31. mysets[ y[i] ].insert ( i );
  32. if ( mysets[ positiveClass ].size() == 0 )
  33. fthrow(Exception, "Class " << positiveClass << " is not available.");
  34. // add our positive examples
  35. for ( set<int>::const_iterator i = mysets[positiveClass].begin(); i != mysets[positiveClass].end(); i++ )
  36. positives.insert ( *i );
  37. int Nneg = conf->gI("main", "nneg", 1 );
  38. for ( map<int, set<int> >::const_iterator k = mysets.begin(); k != mysets.end(); k++ )
  39. {
  40. int classno = k->first;
  41. if ( classno == positiveClass )
  42. continue;
  43. const set<int> & s = k->second;
  44. uint ind = 0;
  45. for ( set<int>::const_iterator i = s.begin(); (i != s.end() && ind < Nneg); i++,ind++ )
  46. negatives.insert ( *i );
  47. }
  48. cerr << "Number of positive examples: " << positives.size() << endl;
  49. cerr << "Number of negative examples: " << negatives.size() << endl;
  50. yb.resize(y.size());
  51. int ind = 0;
  52. for ( uint i = 0 ; i < y.size(); i++ )
  53. {
  54. if (positives.find(i) != positives.end()) {
  55. yb[ examples.size() ] = 1.0;
  56. examples.insert( pair<int, int> ( i, ind ) );
  57. ind++;
  58. } else if ( negatives.find(i) != negatives.end() ) {
  59. yb[ examples.size() ] = -1.0;
  60. examples.insert( pair<int, int> ( i, ind ) );
  61. ind++;
  62. }
  63. }
  64. yb.resize( examples.size() );
  65. cerr << "Examples: " << examples.size() << endl;
  66. }
  67. class BlockHIK : public PartialGenericMatrix
  68. {
  69. protected:
  70. const double *data;
  71. int n;
  72. int d;
  73. double noise;
  74. Vector diag;
  75. public:
  76. BlockHIK ( const double *data, int n, int d, double noise ) {
  77. this->data = data;
  78. this->n = n;
  79. this->d = d;
  80. this->noise = noise;
  81. diag.resize(n);
  82. for ( uint i = 0 ; i < n ; i++ )
  83. {
  84. double sum = 0.0;
  85. for ( uint dim = 0 ; dim < d ; dim++ )
  86. sum += data[i * d + dim];
  87. diag[i] = sum;
  88. }
  89. }
  90. /** multiply a sub-matrix with a given vector: Asub * xsub = ysub */
  91. virtual void multiply ( const SetType & rowSet, const SetType & columnSet, NICE::Vector & y, const NICE::Vector & x) const
  92. {
  93. Matrix K;
  94. if ( rowSet.size() == 0 || columnSet.size() == 0 )
  95. fthrow(Exception, "Sets are zero ...weird" );
  96. K.resize(rowSet.size(), columnSet.size());
  97. K.set(0.0);
  98. //run over every dimension and add the corresponding min-values to the entries in the kernel matrix
  99. int dimension = d;
  100. for (int dim = 0; dim < dimension; dim++)
  101. {
  102. int indi = 0;
  103. for ( SetType::const_iterator i = rowSet.begin(); i != rowSet.end(); i++, indi++ )
  104. {
  105. int indj = 0;
  106. int myi = *i;
  107. double vali = data[ myi * d + dim ];
  108. for ( SetType::const_iterator j = columnSet.begin(); j != columnSet.end(); j++, indj++ )
  109. {
  110. int myj = *j;
  111. double valj = data[ myj * d + dim ];
  112. double val = std::min ( valj, vali );
  113. if ( indi >= K.rows() || indj >= K.cols() )
  114. fthrow(Exception, "... weird indices!!" );
  115. K(indi,indj) += val;
  116. if ( myi == myj )
  117. K(indi, indj) += noise / dimension;
  118. }
  119. }
  120. }//dim-loop
  121. y.resize( rowSet.size() );
  122. y = K*x;
  123. }
  124. /** multiply with a vector: A*x = y */
  125. virtual void multiply (NICE::Vector & y, const NICE::Vector & x) const
  126. {
  127. fthrow(Exception, "You do not really want to compute kernel matrices as big as this one!");
  128. }
  129. virtual double getDiagonalElement ( uint i ) const
  130. {
  131. return diag[i] + noise;
  132. }
  133. virtual uint rows() const
  134. {
  135. return n;
  136. }
  137. virtual uint cols() const
  138. {
  139. return n;
  140. }
  141. };
  142. double *createFlatData ( const FeatureMatrix & f )
  143. {
  144. int n = f.get_n();
  145. int d = f.get_d();
  146. double *data = new double [ n * d ];
  147. memset ( data, 0, n*d*sizeof(double) );
  148. for (int dim = 0; dim < d; dim++)
  149. {
  150. const multimap< double, SortedVectorSparse<double>::dataelement> & nonzeroElements = f.getFeatureValues(dim).nonzeroElements();
  151. int nrZeroIndices = f.getNumberOfZeroElementsPerDimension(dim);
  152. if ( nrZeroIndices == n ) continue;
  153. for ( multimap< double, SortedVectorSparse<double>::dataelement>::const_iterator i = nonzeroElements.begin(); i != nonzeroElements.end(); i++)
  154. {
  155. const SortedVectorSparse<double>::dataelement & de = i->second;
  156. uint feat = de.first;
  157. double fval = de.second;
  158. data[ feat*d + dim ] = fval;
  159. }
  160. }
  161. return data;
  162. }
  163. /**
  164. test the basic functionality of fast-hik hyperparameter optimization
  165. */
  166. int main (int argc, char **argv)
  167. {
  168. std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
  169. Config conf ( argc, argv );
  170. string resultsfile = conf.gS("main", "results", "results.txt" );
  171. int positiveClass = conf.gI("main", "positive_class");
  172. cerr << "Positive class is " << positiveClass << endl;
  173. sparse_t data;
  174. NICE::Vector y;
  175. cerr << "Reading ImageNet data ..." << endl;
  176. bool imageNetLocal = conf.gB("main", "imageNetLocal" , false);
  177. string imageNetPath;
  178. if (imageNetLocal)
  179. imageNetPath = "/users2/rodner/data/imagenet/devkit-1.0/";
  180. else
  181. imageNetPath = "/home/dbv/bilder/imagenet/devkit-1.0/";
  182. ImageNetData imageNet ( imageNetPath + "demo/" );
  183. imageNet.getBatchData ( data, y, "train", "training" );
  184. map<int, int> examples;
  185. Vector yb;
  186. selectExamples ( &conf, y, examples, yb );
  187. double noise = conf.gD("main", "noise", 10);
  188. int dimension = conf.gI("main", "dimension", 1000);
  189. int numBins = conf.gI("main", "num_bins", 100);
  190. Quantization q ( numBins );
  191. FastMinKernel fmk ( data, noise, examples, dimension );
  192. GMHIKernel gmk ( &fmk );
  193. bool verbose = true;
  194. int max_iterations = 500;
  195. vector< IterativeLinearSolver * > methods;
  196. ILSConjugateGradients *m = new ILSConjugateGradients(verbose, max_iterations);
  197. m->setTimeAnalysis ( true );
  198. methods.push_back ( m );
  199. for ( vector< IterativeLinearSolver * >::const_iterator i = methods.begin();
  200. i != methods.end(); i++ )
  201. {
  202. IterativeLinearSolver *method = *i;
  203. Vector sol (gmk.cols(), 0.0);
  204. method->solveLin ( gmk, yb, sol );
  205. }
  206. Vector sol ( gmk.cols(), 0.0 );
  207. double *Tlookup = fmk.solveLin( yb, sol, q, NULL, true /* useRandomSubsets */, 100 /* max iterations */, -1, 0.0, true);
  208. int randomSetSize = conf.gI("main", "random_set_size", 60);
  209. int stepComponents = conf.gI("main", "step_components", 50);
  210. GBCDSolver gbcd ( randomSetSize, stepComponents, true );
  211. gbcd.setTimeAnalysis(true);
  212. Vector sol_gbcd;
  213. double *cdata = createFlatData ( fmk.featureMatrix() );
  214. BlockHIK bhik ( cdata, fmk.get_n(), fmk.get_d(), noise );
  215. gbcd.solveLin ( bhik, yb, sol_gbcd );
  216. delete [] cdata;
  217. return 0;
  218. }
  219. #else
  220. int main (int argc, char **argv)
  221. {
  222. std::cerr << "MatIO library is missing in your system - this program will have no effect. " << std::endl;
  223. }
  224. #endif