testImageNetBinaryBruteForce.cpp 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329
  1. /**
  2. * @file testImageNetBinaryBruteForce.cpp
  3. * @brief perform ImageNet tests with binary tasks for OCC using GP mean and variance, sophisticated approximations of both, Parzen Density Estimation and SVDD
  4. * @author Alexander Lütz
  5. * @date 23-05-2012 (dd-mm-yyyy)
  6. */
  7. #include <ctime>
  8. #include <time.h>
  9. #include "core/basics/Config.h"
  10. #include "core/basics/Timer.h"
  11. #include "core/algebra/CholeskyRobust.h"
  12. #include "core/algebra/DiagonalMatrixApprox.h"
  13. #include "core/vector/Algorithms.h"
  14. #include "core/vector/SparseVectorT.h"
  15. #include "vislearning/cbaselib/ClassificationResults.h"
  16. #include "vislearning/baselib/ProgressBar.h"
  17. #include "vislearning/classifier/kernelclassifier/KCMinimumEnclosingBall.h"
  18. #include "fast-hik/tools.h"
  19. #include "fast-hik/MatFileIO.h"
  20. #include "fast-hik/ImageNetData.h"
  21. using namespace std;
  22. using namespace NICE;
  23. using namespace OBJREC;
  24. // --------------- THE KERNEL FUNCTION ( exponential kernel with euclidian distance ) ----------------------
  25. double measureDistance ( const NICE::SparseVector & a, const NICE::SparseVector & b, const double & sigma = 2.0)
  26. {
  27. double inner_sum(0.0);
  28. double d;
  29. //new version, where we needed on average 0.001707 s for each test sample
  30. NICE::SparseVector::const_iterator aIt = a.begin();
  31. NICE::SparseVector::const_iterator bIt = b.begin();
  32. //compute the euclidian distance between both feature vectores (given as SparseVectors)
  33. while ( (aIt != a.end()) && (bIt != b.end()) )
  34. {
  35. if (aIt->first == bIt->first)
  36. {
  37. d = ( aIt->second - bIt->second );
  38. inner_sum += d * d;
  39. aIt++;
  40. bIt++;
  41. }
  42. else if ( aIt->first < bIt->first)
  43. {
  44. inner_sum += aIt->second * aIt->second;
  45. aIt++;
  46. }
  47. else
  48. {
  49. inner_sum += bIt->second * bIt->second;
  50. bIt++;
  51. }
  52. }
  53. //compute remaining values, if b reached the end but not a
  54. while (aIt != a.end())
  55. {
  56. inner_sum += aIt->second * aIt->second;
  57. aIt++;
  58. }
  59. //compute remaining values, if a reached the end but not b
  60. while (bIt != b.end())
  61. {
  62. inner_sum += bIt->second * bIt->second;
  63. bIt++;
  64. }
  65. //normalization of the exponent
  66. inner_sum /= (2.0*sigma*sigma);
  67. //finally, compute the RBF-kernel score (RBF = radial basis function)
  68. return exp(-inner_sum);
  69. }
  70. // --------------- INPUT METHOD ----------------------
  71. void readParameters(string & filename, const int & size, NICE::Vector & parameterVector)
  72. {
  73. //we read the parameters which are given from a Matlab-Script (each line contains a single number, which is the optimal parameter for this class)
  74. parameterVector.resize(size);
  75. parameterVector.set(0.0);
  76. ifstream is(filename.c_str());
  77. if ( !is.good() )
  78. fthrow(IOException, "Unable to read parameters.");
  79. //
  80. string tmp;
  81. int cnt(0);
  82. while (! is.eof())
  83. {
  84. is >> tmp;
  85. parameterVector[cnt] = atof(tmp.c_str());
  86. cnt++;
  87. }
  88. //
  89. is.close();
  90. }
  91. //------------------- TRAINING METHODS --------------------
  92. void inline trainGPVarApprox(NICE::Vector & matrixDInv, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  93. {
  94. std::cerr << "nrOfExamplesPerClass : " << nrOfExamplesPerClass << std::endl;
  95. Timer tTrainPreciseTimer;
  96. tTrainPreciseTimer.start();
  97. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  98. {
  99. matrixDInv.resize(nrOfExamplesPerClass);
  100. matrixDInv.set(0.0);
  101. //compute D
  102. //start with adding some noise, if necessary
  103. if (noise != 0.0)
  104. matrixDInv.set(noise);
  105. else
  106. matrixDInv.set(0.0);
  107. // the approximation creates a diagonal matrix (which is easy to invert)
  108. // with entries equal the row sums of the original kernel matrix
  109. for (int i = 0; i < nrOfExamplesPerClass; i++)
  110. {
  111. for (int j = i; j < nrOfExamplesPerClass; j++)
  112. {
  113. matrixDInv[i] += kernelMatrix(i,j);
  114. if (i != j)
  115. matrixDInv[j] += kernelMatrix(i,j);
  116. }
  117. }
  118. //compute its inverse
  119. for (int i = 0; i < nrOfExamplesPerClass; i++)
  120. {
  121. matrixDInv[i] = 1.0 / matrixDInv[i];
  122. }
  123. }
  124. tTrainPreciseTimer.stop();
  125. std::cerr << "Precise time used for GPVarApprox training class " << classNumber << ": " << tTrainPreciseTimer.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  126. }
  127. void inline trainGPVar(NICE::Matrix & choleskyMatrix, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  128. {
  129. Timer tTrainPrecise;
  130. tTrainPrecise.start();
  131. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  132. {
  133. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  134. choleskyMatrix.resize(nrOfExamplesPerClass, nrOfExamplesPerClass);
  135. choleskyMatrix.set(0.0);
  136. //compute the cholesky decomposition of K in order to compute K^{-1} \cdot k_* for new test samples
  137. cr.robustChol ( kernelMatrix, choleskyMatrix );
  138. }
  139. tTrainPrecise.stop();
  140. std::cerr << "Precise time used for GPVar training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  141. }
  142. void inline trainGPMeanApprox(NICE::Vector & GPMeanApproxRightPart, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  143. {
  144. Timer tTrainPrecise;
  145. tTrainPrecise.start();
  146. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  147. {
  148. NICE::Vector matrixDInv(nrOfExamplesPerClass,0.0);
  149. //compute D
  150. //start with adding some noise, if necessary
  151. if (noise != 0.0)
  152. matrixDInv.set(noise);
  153. else
  154. matrixDInv.set(0.0);
  155. // the approximation creates a diagonal matrix (which is easy to invert)
  156. // with entries equal the row sums of the original kernel matrix
  157. for (int i = 0; i < nrOfExamplesPerClass; i++)
  158. {
  159. for (int j = i; j < nrOfExamplesPerClass; j++)
  160. {
  161. matrixDInv[i] += kernelMatrix(i,j);
  162. if (i != j)
  163. matrixDInv[j] += kernelMatrix(i,j);
  164. }
  165. }
  166. //compute its inverse (and multiply every element with the label vector, which contains only one-entries and therefore be skipped...)
  167. GPMeanApproxRightPart.resize(nrOfExamplesPerClass);
  168. for (int i = 0; i < nrOfExamplesPerClass; i++)
  169. {
  170. GPMeanApproxRightPart[i] = 1.0 / matrixDInv[i];
  171. }
  172. }
  173. tTrainPrecise.stop();
  174. std::cerr << "Precise time used for GPMeanApprox training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  175. }
  176. void inline trainGPMean(NICE::Vector & GPMeanRightPart, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  177. {
  178. Timer tTrainPrecise;
  179. tTrainPrecise.start();
  180. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  181. {
  182. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  183. NICE::Matrix choleskyMatrix (nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0);
  184. //compute the cholesky decomposition of K in order to compute K^{-1} \cdot y
  185. cr.robustChol ( kernelMatrix, choleskyMatrix );
  186. GPMeanRightPart.resize(nrOfExamplesPerClass);
  187. GPMeanRightPart.set(0.0);
  188. NICE::Vector y(nrOfExamplesPerClass,1.0); //OCC setting :)
  189. // pre-compute K^{-1} \cdot y, which is the same for every new test sample
  190. choleskySolveLargeScale ( choleskyMatrix, y, GPMeanRightPart );
  191. }
  192. tTrainPrecise.stop();
  193. std::cerr << "Precise time used for GPMean training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  194. }
  195. // GP subset of regressors
  196. void inline trainGPSRMean(NICE::Vector & GPMeanRightPart, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining, const int & nrOfRegressors, std::vector<int> & indicesOfChosenExamples )
  197. {
  198. std::vector<int> examplesToChoose;
  199. indicesOfChosenExamples.clear();
  200. //add all examples for possible choice
  201. for (int i = 0; i < nrOfExamplesPerClass; i++)
  202. {
  203. examplesToChoose.push_back(i);
  204. }
  205. //now chose randomly some examples as active subset
  206. int index;
  207. for (int i = 0; i < std::min(nrOfRegressors,nrOfExamplesPerClass); i++)
  208. {
  209. index = rand() % examplesToChoose.size();
  210. indicesOfChosenExamples.push_back(examplesToChoose[index]);
  211. examplesToChoose.erase(examplesToChoose.begin() + index);
  212. }
  213. NICE::Matrix Kmn (indicesOfChosenExamples.size(), nrOfExamplesPerClass, 0.0);
  214. int rowCnt(0);
  215. //set every row
  216. for (int i = 0; i < indicesOfChosenExamples.size(); i++, rowCnt++ )
  217. {
  218. //set every element of this row
  219. NICE::Vector col = kernelMatrix.getRow(indicesOfChosenExamples[i]);
  220. for (int j = 0; j < nrOfExamplesPerClass; j++)
  221. {
  222. Kmn(rowCnt,j) = col(j);
  223. }
  224. }
  225. //we could speed this up if we would order the indices
  226. NICE::Matrix Kmm (indicesOfChosenExamples.size(), indicesOfChosenExamples.size(), 0.0);
  227. double tmp(0.0);
  228. for (int i = 0; i < indicesOfChosenExamples.size(); i++ )
  229. {
  230. for (int j = i; j < indicesOfChosenExamples.size(); j++ )
  231. {
  232. tmp = kernelMatrix(indicesOfChosenExamples[i], indicesOfChosenExamples[j]);
  233. Kmm(i,j) = tmp;
  234. if (i != j)
  235. Kmm(j,i) = tmp;
  236. }
  237. }
  238. Timer tTrainPrecise;
  239. tTrainPrecise.start();
  240. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  241. {
  242. NICE::Matrix innerMatrix;
  243. innerMatrix.multiply(Kmn, Kmn, false /* tranpose first matrix*/, true /* transpose second matrix*/);
  244. innerMatrix.addScaledMatrix( noise, Kmm );
  245. NICE::Vector y(nrOfExamplesPerClass,1.0); //OCC setting :)
  246. NICE::Vector projectedLabels;
  247. projectedLabels.multiply(Kmn,y);
  248. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  249. NICE::Matrix choleskyMatrix (nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0);
  250. //compute the cholesky decomposition of K in order to compute K^{-1} \cdot y
  251. cr.robustChol ( innerMatrix, choleskyMatrix );
  252. GPMeanRightPart.resize(indicesOfChosenExamples.size());
  253. GPMeanRightPart.set(0.0);
  254. // pre-compute K^{-1} \cdot y, which is the same for every new test sample
  255. choleskySolveLargeScale ( choleskyMatrix, projectedLabels, GPMeanRightPart );
  256. }
  257. tTrainPrecise.stop();
  258. std::cerr << "Precise time used for GPSRMean training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  259. }
  260. // GP subset of regressors
  261. void inline trainGPSRVar(NICE::Matrix & choleskyMatrix, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining, const int & nrOfRegressors, std::vector<int> & indicesOfChosenExamples )
  262. {
  263. std::vector<int> examplesToChoose;
  264. indicesOfChosenExamples.clear();
  265. //add all examples for possible choice
  266. for (int i = 0; i < nrOfExamplesPerClass; i++)
  267. {
  268. examplesToChoose.push_back(i);
  269. }
  270. //now chose randomly some examples as active subset
  271. int index;
  272. for (int i = 0; i < std::min(nrOfRegressors,nrOfExamplesPerClass); i++)
  273. {
  274. index = rand() % examplesToChoose.size();
  275. indicesOfChosenExamples.push_back(examplesToChoose[index]);
  276. examplesToChoose.erase(examplesToChoose.begin() + index);
  277. }
  278. NICE::Matrix Kmn (indicesOfChosenExamples.size(), nrOfExamplesPerClass, 0.0);
  279. int rowCnt(0);
  280. //set every row
  281. for (int i = 0; i < indicesOfChosenExamples.size(); i++, rowCnt++ )
  282. {
  283. //set every element of this row
  284. NICE::Vector col = kernelMatrix.getRow(indicesOfChosenExamples[i]);
  285. for (int j = 0; j < nrOfExamplesPerClass; j++)
  286. {
  287. Kmn(rowCnt,j) = col(j);
  288. }
  289. }
  290. //we could speed this up if we would order the indices
  291. NICE::Matrix Kmm (indicesOfChosenExamples.size(), indicesOfChosenExamples.size(), 0.0);
  292. double tmp(0.0);
  293. for (int i = 0; i < indicesOfChosenExamples.size(); i++ )
  294. {
  295. for (int j = i; j < indicesOfChosenExamples.size(); j++ )
  296. {
  297. tmp = kernelMatrix(indicesOfChosenExamples[i], indicesOfChosenExamples[j]);
  298. Kmm(i,j) = tmp;
  299. if (i != j)
  300. Kmm(j,i) = tmp;
  301. }
  302. }
  303. Timer tTrainPrecise;
  304. tTrainPrecise.start();
  305. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  306. {
  307. NICE::Matrix innerMatrix;
  308. innerMatrix.multiply(Kmn, Kmn, false /* tranpose first matrix*/, true /* transpose second matrix*/);
  309. innerMatrix.addScaledMatrix( noise, Kmm );
  310. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  311. choleskyMatrix.resize( nrOfExamplesPerClass, nrOfExamplesPerClass );
  312. choleskyMatrix.set( 0.0 );
  313. //compute the cholesky decomposition of K in order to compute K^{-1} \cdot y
  314. cr.robustChol ( innerMatrix, choleskyMatrix );
  315. }
  316. tTrainPrecise.stop();
  317. std::cerr << "Precise time used for GPSRVar training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  318. }
  319. void inline trainGPOptMean(NICE::Vector & rightPartGPOptMean, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  320. {
  321. DiagonalMatrixApprox diagApprox ( true /*verbose*/ );
  322. Timer tTrainPrecise;
  323. tTrainPrecise.start();
  324. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  325. {
  326. //compute optimal diagonal matrix
  327. diagApprox.approx ( kernelMatrix, rightPartGPOptMean );
  328. // invert entries
  329. // by theory we should multiply these entries with the labels
  330. // but we are in an OCC setting with labels equal to one
  331. for (int i = 0; i < nrOfExamplesPerClass; i++)
  332. {
  333. if (rightPartGPOptMean[i] != 0.0)
  334. rightPartGPOptMean[i] = 1.0 / rightPartGPOptMean[i];
  335. }
  336. }
  337. tTrainPrecise.stop();
  338. std::cerr << "Precise time used for GPOptMean training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  339. }
  340. void inline trainGPOptVar(NICE::Vector & DiagGPOptVar, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  341. {
  342. DiagonalMatrixApprox diagApprox ( true /*verbose*/ );
  343. Timer tTrainPrecise;
  344. tTrainPrecise.start();
  345. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  346. {
  347. //compute optimal diagonal matrix
  348. diagApprox.approx ( kernelMatrix, DiagGPOptVar );
  349. //invert entries
  350. for (int i = 0; i < nrOfExamplesPerClass; i++)
  351. {
  352. if (DiagGPOptVar[i] != 0.0)
  353. DiagGPOptVar[i] = 1.0 / DiagGPOptVar[i];
  354. }
  355. }
  356. tTrainPrecise.stop();
  357. std::cerr << "Precise time used for GPOptVar training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  358. }
  359. KCMinimumEnclosingBall *trainSVDD( const double & noise, const NICE::Matrix kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  360. {
  361. Config conf;
  362. // set the outlier ratio (Paul optimized this paramter FIXME)
  363. conf.sD( "SVDD", "outlier_fraction", 0.1 );
  364. conf.sB( "SVDD", "verbose", false );
  365. KCMinimumEnclosingBall *svdd = new KCMinimumEnclosingBall ( &conf, NULL /* no kernel function */, "SVDD" /* config section */);
  366. KernelData kernelData ( &conf, kernelMatrix, "Kernel" , false /* update cholesky */ );
  367. Timer tTrainPrecise;
  368. tTrainPrecise.start();
  369. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  370. {
  371. NICE::Vector y(nrOfExamplesPerClass,1.0); //OCC setting :)
  372. // KCMinimumEnclosingBall does not store the kernel data object, therefore, we are save with passing a local copy
  373. svdd->teach ( &kernelData, y );
  374. }
  375. tTrainPrecise.stop();
  376. std::cerr << "Precise time used for SVDD training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  377. return svdd;
  378. }
  379. // ------------- EVALUATION METHODS ---------------------
  380. void inline evaluateGPVarApprox(const NICE::Vector & kernelVector, const double & kernelSelf, const NICE::Vector & matrixDInv, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  381. {
  382. double uncertainty;
  383. Timer tTestSingle;
  384. tTestSingle.start();
  385. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  386. {
  387. // uncertainty = k{**} - \k_*^T \cdot D^{-1} \cdot k_* where D is our nice approximation of K
  388. NICE::Vector rightPart (kernelVector.size());
  389. for (int j = 0; j < kernelVector.size(); j++)
  390. {
  391. rightPart[j] = kernelVector[j] * matrixDInv[j];
  392. }
  393. uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  394. }
  395. tTestSingle.stop();
  396. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  397. FullVector scores ( 2 );
  398. scores[0] = 0.0;
  399. scores[1] = 1.0 - uncertainty;
  400. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  401. }
  402. void inline evaluateGPVar(const NICE::Vector & kernelVector, const double & kernelSelf, const NICE::Matrix & choleskyMatrix, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  403. {
  404. double uncertainty;
  405. Timer tTestSingle;
  406. tTestSingle.start();
  407. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  408. {
  409. // uncertainty = k{**} - \k_*^T \cdot D^{-1} \cdot k_*
  410. NICE::Vector rightPart (kernelVector.size(),0.0);
  411. choleskySolveLargeScale ( choleskyMatrix, kernelVector, rightPart );
  412. uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  413. }
  414. tTestSingle.stop();
  415. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  416. FullVector scores ( 2 );
  417. scores[0] = 0.0;
  418. scores[1] = 1.0 - uncertainty;
  419. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  420. }
  421. void inline evaluateGPMeanApprox(const NICE::Vector & kernelVector, const NICE::Vector & rightPart, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  422. {
  423. double mean;
  424. Timer tTestSingle;
  425. tTestSingle.start();
  426. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  427. {
  428. // \mean = \k_*^T \cdot D^{-1} \cdot y where D is our nice approximation of K
  429. mean = kernelVector.scalarProduct ( rightPart );
  430. }
  431. tTestSingle.stop();
  432. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  433. FullVector scores ( 2 );
  434. scores[0] = 0.0;
  435. scores[1] = mean;
  436. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  437. }
  438. void inline evaluateGPMean(const NICE::Vector & kernelVector, const NICE::Vector & GPMeanRightPart, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  439. {
  440. double mean;
  441. Timer tTestSingle;
  442. tTestSingle.start();
  443. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  444. {
  445. // \mean = \k_*^T \cdot K^{-1} \cdot y
  446. mean = kernelVector.scalarProduct ( GPMeanRightPart );
  447. }
  448. tTestSingle.stop();
  449. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  450. FullVector scores ( 2 );
  451. scores[0] = 0.0;
  452. scores[1] = mean;
  453. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  454. }
  455. void inline evaluateGPSRMean(const NICE::Vector & kernelVector, const NICE::Vector & GPSRMeanRightPart, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting, const int & nrOfRegressors, const std::vector<int> & indicesOfChosenExamples)
  456. {
  457. double mean;
  458. //grep the entries corresponding to the active set
  459. NICE::Vector kernelVectorM;
  460. kernelVectorM.resize(nrOfRegressors);
  461. for (int i = 0; i < nrOfRegressors; i++)
  462. {
  463. kernelVectorM[i] = kernelVector[indicesOfChosenExamples[i]];
  464. }
  465. Timer tTestSingle;
  466. tTestSingle.start();
  467. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  468. {
  469. // \mean = \k_*^T \cdot K^{-1} \cdot y
  470. mean = kernelVectorM.scalarProduct ( GPSRMeanRightPart );
  471. }
  472. tTestSingle.stop();
  473. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  474. FullVector scores ( 2 );
  475. scores[0] = 0.0;
  476. scores[1] = mean;
  477. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  478. }
  479. void inline evaluateGPSRVar(const NICE::Vector & kernelVector, const NICE::Matrix & choleskyMatrix, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting, const int & nrOfRegressors, std::vector<int> & indicesOfChosenExamples, const double & noise)
  480. {
  481. double uncertainty;
  482. //grep the entries corresponding to the active set
  483. NICE::Vector kernelVectorM;
  484. kernelVectorM.resize(nrOfRegressors);
  485. for (int i = 0; i < nrOfRegressors; i++)
  486. {
  487. kernelVectorM[i] = kernelVector[indicesOfChosenExamples[i]];
  488. }
  489. Timer tTestSingle;
  490. tTestSingle.start();
  491. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  492. {
  493. NICE::Vector rightPart (nrOfRegressors,0.0);
  494. choleskySolveLargeScale ( choleskyMatrix, kernelVectorM, rightPart );
  495. uncertainty = noise*kernelVectorM.scalarProduct ( rightPart );
  496. }
  497. tTestSingle.stop();
  498. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  499. FullVector scores ( 2 );
  500. scores[0] = 0.0;
  501. scores[1] = 1.0 - uncertainty;
  502. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  503. }
  504. //this method is completely the same as evaluateGPMeanApprox, but for convenience, it is its own method
  505. void inline evaluateGPOptMean(const NICE::Vector & kernelVector, const NICE::Vector & rightPart, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  506. {
  507. double mean;
  508. Timer tTestSingle;
  509. tTestSingle.start();
  510. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  511. {
  512. // \mean = \k_*^T \cdot D^{-1} \cdot y where D is our nice approximation of K
  513. mean = kernelVector.scalarProduct ( rightPart );
  514. }
  515. tTestSingle.stop();
  516. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  517. FullVector scores ( 2 );
  518. scores[0] = 0.0;
  519. scores[1] = mean;
  520. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  521. }
  522. //this method is completely the same as evaluateGPVarApprox, but for convenience, it is its own method
  523. void inline evaluateGPOptVar(const NICE::Vector & kernelVector, const double & kernelSelf, const NICE::Vector & matrixDInv, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  524. {
  525. double uncertainty;
  526. Timer tTestSingle;
  527. tTestSingle.start();
  528. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  529. {
  530. // uncertainty = k{**} - \k_*^T \cdot D^{-1} \cdot k_* where D is our nice approximation of K
  531. NICE::Vector rightPart (kernelVector.size());
  532. for (int j = 0; j < kernelVector.size(); j++)
  533. {
  534. rightPart[j] = kernelVector[j] * matrixDInv[j];
  535. }
  536. uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  537. }
  538. tTestSingle.stop();
  539. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  540. FullVector scores ( 2 );
  541. scores[0] = 0.0;
  542. scores[1] = 1.0 - uncertainty;
  543. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  544. }
  545. void inline evaluateParzen(const NICE::Vector & kernelVector, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  546. {
  547. double score;
  548. Timer tTestSingle;
  549. tTestSingle.start();
  550. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  551. {
  552. //the Parzen score is nothing but the averaged similarity to every training sample
  553. score = kernelVector.Sum() / (double) kernelVector.size(); //maybe we could directly call kernelVector.Mean() here
  554. }
  555. tTestSingle.stop();
  556. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  557. FullVector scores ( 2 );
  558. scores[0] = 0.0;
  559. scores[1] = score;
  560. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  561. }
  562. void inline evaluateSVDD( KCMinimumEnclosingBall *svdd, const NICE::Vector & kernelVector, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  563. {
  564. Timer tTestSingle;
  565. tTestSingle.start();
  566. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  567. {
  568. // In the following, we assume that we are using a Gaussian kernel
  569. r = svdd->classifyKernel ( kernelVector, 1.0 /* kernel self */ );
  570. }
  571. tTestSingle.stop();
  572. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  573. }
  574. /**
  575. test the basic functionality of fast-hik hyperparameter optimization
  576. */
  577. int main (int argc, char **argv)
  578. {
  579. std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
  580. Config conf ( argc, argv );
  581. string resultsfile = conf.gS("main", "results", "results.txt" );
  582. int nrOfExamplesPerClass = conf.gI("main", "nrOfExamplesPerClass", 50);
  583. nrOfExamplesPerClass = std::min(nrOfExamplesPerClass, 100); // we do not have more than 100 examples per class
  584. //which classes to considere? we assume consecutive class numers
  585. int indexOfFirstClass = conf.gI("main", "indexOfFirstClass", 0);
  586. indexOfFirstClass = std::max(indexOfFirstClass, 0); //we do not have less than 0 classes
  587. int indexOfLastClass = conf.gI("main", "indexOfLastClass", 999);
  588. indexOfLastClass = std::min(indexOfLastClass, 999); //we do not have more than 1000 classes
  589. int nrOfClassesToConcidere = (indexOfLastClass - indexOfLastClass)+1;
  590. //repetitions for every class to achieve reliable time evalutions
  591. int runsPerClassToAverageTraining = conf.gI( "main", "runsPerClassToAverageTraining", 1 );
  592. int runsPerClassToAverageTesting = conf.gI( "main", "runsPerClassToAverageTesting", 1 );
  593. // share parameters among methods and classes?
  594. bool shareParameters = conf.gB("main" , "shareParameters", true);
  595. //which methods do we want to use?
  596. bool GPMeanApprox = conf.gB( "main", "GPMeanApprox", false);
  597. bool GPVarApprox = conf.gB( "main", "GPVarApprox", false);
  598. bool GPMean = conf.gB( "main", "GPMean", false);
  599. bool GPVar = conf.gB( "main", "GPVar", false);
  600. bool GPSRMean = conf.gB( "main", "GPSRMean", false);
  601. bool GPSRVar = conf.gB( "main", "GPSRVar", false);
  602. bool GPOptMean = conf.gB( "main", "GPOptMean", false);
  603. bool GPOptVar = conf.gB( "main", "GPOptVar", false);
  604. bool Parzen = conf.gB( "main", "Parzen", false);
  605. bool SVDD = conf.gB( "main", "SVDD", false);
  606. if (GPMeanApprox)
  607. std::cerr << "GPMeanApprox used" << std::endl;
  608. else
  609. std::cerr << "GPMeanApprox not used" << std::endl;
  610. if (GPVarApprox)
  611. std::cerr << "GPVarApprox used" << std::endl;
  612. else
  613. std::cerr << "GPVarApprox not used" << std::endl;
  614. if (GPMean)
  615. std::cerr << "GPMean used" << std::endl;
  616. else
  617. std::cerr << "GPMean not used" << std::endl;
  618. if (GPVar)
  619. std::cerr << "GPVar used" << std::endl;
  620. else
  621. std::cerr << "GPVar not used" << std::endl;
  622. if (GPSRMean)
  623. std::cerr << "GPSRMean used" << std::endl;
  624. else
  625. std::cerr << "GPSRMean not used" << std::endl;
  626. if (GPSRVar)
  627. std::cerr << "GPSRVar used" << std::endl;
  628. else
  629. std::cerr << "GPSRVar not used" << std::endl;
  630. if (GPOptMean)
  631. std::cerr << "GPOptMean used" << std::endl;
  632. else
  633. std::cerr << "GPOptMean not used" << std::endl;
  634. if (GPOptVar)
  635. std::cerr << "GPOptVar used" << std::endl;
  636. else
  637. std::cerr << "GPOptVar not used" << std::endl;
  638. if (Parzen)
  639. std::cerr << "Parzen used" << std::endl;
  640. else
  641. std::cerr << "Parzen not used" << std::endl;
  642. if (SVDD)
  643. std::cerr << "SVDD used" << std::endl;
  644. else
  645. std::cerr << "SVDD not used" << std::endl;
  646. // GP variance approximation
  647. NICE::Vector sigmaGPVarApproxParas(nrOfClassesToConcidere,0.0);
  648. NICE::Vector noiseGPVarApproxParas(nrOfClassesToConcidere,0.0);
  649. // GP variance
  650. NICE::Vector sigmaGPVarParas(nrOfClassesToConcidere,0.0);
  651. NICE::Vector noiseGPVarParas(nrOfClassesToConcidere,0.0);
  652. //GP mean approximation
  653. NICE::Vector sigmaGPMeanApproxParas(nrOfClassesToConcidere,0.0);
  654. NICE::Vector noiseGPMeanApproxParas(nrOfClassesToConcidere,0.0);
  655. //GP mean
  656. NICE::Vector sigmaGPMeanParas(nrOfClassesToConcidere,0.0);
  657. NICE::Vector noiseGPMeanParas(nrOfClassesToConcidere,0.0);
  658. //GP SR mean
  659. NICE::Vector sigmaGPSRMeanParas(nrOfClassesToConcidere,0.0);
  660. NICE::Vector noiseGPSRMeanParas(nrOfClassesToConcidere,0.0);
  661. //GP SR var
  662. NICE::Vector sigmaGPSRVarParas(nrOfClassesToConcidere,0.0);
  663. NICE::Vector noiseGPSRVarParas(nrOfClassesToConcidere,0.0);
  664. //GP Opt mean
  665. NICE::Vector sigmaGPOptMeanParas(nrOfClassesToConcidere,0.0);
  666. NICE::Vector noiseGPOptMeanParas(nrOfClassesToConcidere,0.0);
  667. //GP Opt var
  668. NICE::Vector sigmaGPOptVarParas(nrOfClassesToConcidere,0.0);
  669. NICE::Vector noiseGPOptVarParas(nrOfClassesToConcidere,0.0);
  670. //Parzen
  671. NICE::Vector sigmaParzenParas(nrOfClassesToConcidere,0.0);
  672. NICE::Vector noiseParzenParas(nrOfClassesToConcidere,0.0);
  673. //SVDD
  674. NICE::Vector sigmaSVDDParas(nrOfClassesToConcidere,0.0);
  675. NICE::Vector noiseSVDDParas(nrOfClassesToConcidere,0.0);
  676. if (!shareParameters)
  677. {
  678. //read the optimal parameters for the different methods
  679. // GP variance approximation
  680. string sigmaGPVarApproxFile = conf.gS("main", "sigmaGPVarApproxFile", "approxVarSigma.txt");
  681. string noiseGPVarApproxFile = conf.gS("main", "noiseGPVarApproxFile", "approxVarNoise.txt");
  682. // GP variance
  683. string sigmaGPVarFile = conf.gS("main", "sigmaGPVarFile", "approxVarSigma.txt");
  684. string noiseGPVarFile = conf.gS("main", "noiseGPVarFile", "approxVarNoise.txt");
  685. //GP mean approximation
  686. string sigmaGPMeanApproxFile = conf.gS("main", "sigmaGPMeanApproxFile", "approxVarSigma.txt");
  687. string noiseGPMeanApproxFile = conf.gS("main", "noiseGPMeanApproxFile", "approxVarNoise.txt");
  688. //GP mean
  689. string sigmaGPMeanFile = conf.gS("main", "sigmaGPMeanFile", "approxVarSigma.txt");
  690. string noiseGPMeanFile = conf.gS("main", "noiseGPMeanFile", "approxVarNoise.txt");
  691. //Parzen
  692. string sigmaParzenFile = conf.gS("main", "sigmaParzenFile", "approxVarSigma.txt");
  693. string noiseParzenFile = conf.gS("main", "noiseParzenFile", "approxVarNoise.txt");
  694. //SVDD
  695. string sigmaSVDDFile = conf.gS("main", "sigmaSVDDFile", "approxVarSigma.txt");
  696. string noiseSVDDFile = conf.gS("main", "noiseSVDDFile", "approxVarNoise.txt");
  697. // GP variance approximation
  698. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPVarApproxParas);
  699. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPVarApproxParas);
  700. // GP variance
  701. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPVarParas);
  702. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPVarParas);
  703. //GP mean approximation
  704. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPMeanApproxParas);
  705. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPMeanApproxParas);
  706. //GP mean
  707. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPMeanParas);
  708. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPMeanParas);
  709. //GP SR mean
  710. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPSRMeanParas);
  711. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPSRMeanParas);
  712. //GP SR var
  713. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPSRVarParas);
  714. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPSRVarParas);
  715. //GP Opt mean
  716. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPOptMeanParas);
  717. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPOptMeanParas);
  718. //GP Opt var
  719. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPOptVarParas);
  720. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPOptVarParas);
  721. //Parzen
  722. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaParzenParas);
  723. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseParzenParas);
  724. //SVDD
  725. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaSVDDParas);
  726. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseSVDDParas);
  727. }
  728. else
  729. {
  730. //use static variables for all methods and classis
  731. double noise = conf.gD( "main", "noise", 0.01 );
  732. double sigma = conf.gD( "main", "sigma", 1.0 );
  733. sigmaGPVarApproxParas.set(sigma);
  734. noiseGPVarApproxParas.set(noise);
  735. // GP variance
  736. sigmaGPVarParas.set(sigma);
  737. noiseGPVarParas.set(noise);
  738. //GP mean approximation
  739. sigmaGPMeanApproxParas.set(sigma);
  740. noiseGPMeanApproxParas.set(noise);
  741. //GP mean
  742. sigmaGPMeanParas.set(sigma);
  743. noiseGPMeanParas.set(noise);
  744. //GP SR mean
  745. sigmaGPSRMeanParas.set(sigma);
  746. noiseGPSRMeanParas.set(noise);
  747. //GP SR var
  748. sigmaGPSRVarParas.set(sigma);
  749. noiseGPSRVarParas.set(noise);
  750. //GP Opt mean
  751. sigmaGPOptMeanParas.set(sigma);
  752. noiseGPOptMeanParas.set(noise);
  753. //GP Opt var
  754. sigmaGPOptVarParas.set(sigma);
  755. noiseGPOptVarParas.set(noise);
  756. //Parzen
  757. sigmaParzenParas.set(sigma);
  758. noiseParzenParas.set(noise);
  759. //SVDD
  760. sigmaSVDDParas.set(sigma);
  761. noiseSVDDParas.set(noise);
  762. }
  763. // -------- optimal parameters read --------------
  764. std::vector<SparseVector> trainingData;
  765. NICE::Vector y;
  766. std::cerr << "Reading ImageNet data ..." << std::endl;
  767. bool imageNetLocal = conf.gB("main", "imageNetLocal" , false);
  768. string imageNetPath;
  769. if (imageNetLocal)
  770. imageNetPath = "/users2/rodner/data/imagenet/devkit-1.0/";
  771. else
  772. imageNetPath = "/home/dbv/bilder/imagenet/devkit-1.0/";
  773. ImageNetData imageNetTrain ( imageNetPath + "demo/" );
  774. imageNetTrain.preloadData( "train", "training" );
  775. trainingData = imageNetTrain.getPreloadedData();
  776. y = imageNetTrain.getPreloadedLabels();
  777. std::cerr << "Reading of training data finished" << std::endl;
  778. std::cerr << "trainingData.size(): " << trainingData.size() << std::endl;
  779. std::cerr << "y.size(): " << y.size() << std::endl;
  780. std::cerr << "Reading ImageNet test data files (takes some seconds)..." << std::endl;
  781. ImageNetData imageNetTest ( imageNetPath + "demo/" );
  782. imageNetTest.preloadData ( "val", "testing" );
  783. imageNetTest.loadExternalLabels ( imageNetPath + "data/ILSVRC2010_validation_ground_truth.txt" );
  784. double OverallPerformanceGPVarApprox(0.0);
  785. double OverallPerformanceGPVar(0.0);
  786. double OverallPerformanceGPMeanApprox(0.0);
  787. double OverallPerformanceGPMean(0.0);
  788. double OverallPerformanceGPSRMean(0.0);
  789. double OverallPerformanceGPSRVar(0.0);
  790. double OverallPerformanceGPOptMean(0.0);
  791. double OverallPerformanceGPOptVar(0.0);
  792. double OverallPerformanceParzen(0.0);
  793. double OverallPerformanceSVDD(0.0);
  794. double kernelSigmaGPVarApprox;
  795. double kernelSigmaGPVar;
  796. double kernelSigmaGPMeanApprox;
  797. double kernelSigmaGPMean;
  798. double kernelSigmaGPSRMean;
  799. double kernelSigmaGPSRVar;
  800. double kernelSigmaGPOptMean;
  801. double kernelSigmaGPOptVar;
  802. double kernelSigmaParzen;
  803. double kernelSigmaSVDD;
  804. for (int cl = indexOfFirstClass; cl <= indexOfLastClass; cl++)
  805. {
  806. std::cerr << "run for class " << cl << std::endl;
  807. int positiveClass = cl+1; //labels are from 1 to 1000, but our indices from 0 to 999
  808. // ------------------------------ TRAINING ------------------------------
  809. kernelSigmaGPVarApprox = sigmaGPVarApproxParas[cl];
  810. kernelSigmaGPVar = sigmaGPVarParas[cl];
  811. kernelSigmaGPMeanApprox = sigmaGPMeanApproxParas[cl];
  812. kernelSigmaGPMean = sigmaGPMeanParas[cl];
  813. kernelSigmaGPSRMean = sigmaGPSRMeanParas[cl];
  814. kernelSigmaGPSRVar = sigmaGPSRVarParas[cl];
  815. kernelSigmaGPOptMean = sigmaGPOptMeanParas[cl];
  816. kernelSigmaGPOptVar = sigmaGPOptVarParas[cl];
  817. kernelSigmaParzen = sigmaParzenParas[cl];
  818. kernelSigmaSVDD = sigmaSVDDParas[cl];
  819. Timer tTrain;
  820. tTrain.start();
  821. //compute the kernel matrix, which will be shared among all methods in this scenario
  822. NICE::Matrix kernelMatrix(nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0);
  823. //NOTE in theory we have to compute a single kernel Matrix for every method, since every method may have its own optimal parameter
  824. // I'm sure, we can speed it up a bit and compute it only for every different parameter
  825. //nonetheless, it's not as nice as we originally thought (same matrix for every method)
  826. //NOTE Nonetheless, since we're only interested in runtimes, we can ignore this
  827. //now sum up all entries of each row in the original kernel matrix
  828. double kernelScore(0.0);
  829. for (int i = cl*100; i < cl*100+nrOfExamplesPerClass; i++)
  830. {
  831. for (int j = i; j < cl*100+nrOfExamplesPerClass; j++)
  832. {
  833. kernelScore = measureDistance(trainingData[i],trainingData[j], kernelSigmaGPVarApprox);
  834. kernelMatrix(i-cl*100,j-cl*100) = kernelScore;
  835. if (i != j)
  836. kernelMatrix(j-cl*100,i-cl*100) = kernelScore;
  837. }
  838. }
  839. // now call the individual training methods
  840. //train GP Var Approx
  841. NICE::Vector matrixDInv;
  842. if (GPVarApprox)
  843. trainGPVarApprox(matrixDInv, noiseGPVarApproxParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  844. //train GP Var
  845. NICE::Matrix GPVarCholesky;
  846. if (GPVar)
  847. trainGPVar(GPVarCholesky, noiseGPVarParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  848. //train GP Mean Approx
  849. NICE::Vector GPMeanApproxRightPart;
  850. if (GPMeanApprox)
  851. trainGPMeanApprox(GPMeanApproxRightPart, noiseGPMeanApproxParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  852. //train GP Mean
  853. NICE::Vector GPMeanRightPart;
  854. if (GPMean)
  855. trainGPMean(GPMeanRightPart, noiseGPMeanParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  856. //train GP SR Mean
  857. NICE::Vector GPSRMeanRightPart;
  858. std::vector<int> indicesOfChosenExamplesGPSRMean;
  859. int nrOfRegressors = conf.gI( "GPSR", "nrOfRegressors", nrOfExamplesPerClass/2);
  860. nrOfRegressors = std::min( nrOfRegressors, nrOfExamplesPerClass );
  861. if (GPSRMean)
  862. trainGPSRMean(GPSRMeanRightPart, noiseGPSRMeanParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining, nrOfRegressors, indicesOfChosenExamplesGPSRMean );
  863. //train GP SR Var
  864. NICE::Matrix GPSRVarCholesky;
  865. std::vector<int> indicesOfChosenExamplesGPSRVar;
  866. if (GPSRVar)
  867. trainGPSRVar(GPSRVarCholesky, noiseGPSRVarParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining, nrOfRegressors, indicesOfChosenExamplesGPSRVar );
  868. //train GP Opt Mean
  869. NICE::Vector GPOptMeanRightPart;
  870. if (GPOptMean)
  871. trainGPMeanApprox(GPOptMeanRightPart, noiseGPOptMeanParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  872. //train GP Opt Var
  873. NICE::Vector DiagGPOptVar;
  874. if (GPOptVar)
  875. trainGPMean(DiagGPOptVar, noiseGPOptVarParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  876. //train Parzen
  877. //nothing to do :)
  878. //train SVDD
  879. KCMinimumEnclosingBall *svdd;
  880. if (SVDD)
  881. svdd = trainSVDD(noiseSVDDParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  882. tTrain.stop();
  883. std::cerr << "Time used for training class " << cl << ": " << tTrain.getLast() << std::endl;
  884. std::cerr << "training done - now perform the evaluation" << std::endl;
  885. // ------------------------------ TESTING ------------------------------
  886. std::cerr << "Classification step ... with " << imageNetTest.getNumPreloadedExamples() << " examples" << std::endl;
  887. ClassificationResults resultsGPVarApprox;
  888. ClassificationResults resultsGPVar;
  889. ClassificationResults resultsGPMeanApprox;
  890. ClassificationResults resultsGPMean;
  891. ClassificationResults resultsGPSRMean;
  892. ClassificationResults resultsGPSRVar;
  893. ClassificationResults resultsGPOptMean;
  894. ClassificationResults resultsGPOptVar;
  895. ClassificationResults resultsParzen;
  896. ClassificationResults resultsSVDD;
  897. ProgressBar pb;
  898. Timer tTest;
  899. tTest.start();
  900. Timer tTestSingle;
  901. double timeForSingleExamplesGPVarApprox(0.0);
  902. double timeForSingleExamplesGPVar(0.0);
  903. double timeForSingleExamplesGPMeanApprox(0.0);
  904. double timeForSingleExamplesGPMean(0.0);
  905. double timeForSingleExamplesGPSRMean(0.0);
  906. double timeForSingleExamplesGPSRVar(0.0);
  907. double timeForSingleExamplesGPOptMean(0.0);
  908. double timeForSingleExamplesGPOptVar(0.0);
  909. double timeForSingleExamplesParzen(0.0);
  910. double timeForSingleExamplesSVDD(0.0);
  911. for ( uint i = 0 ; i < (uint)imageNetTest.getNumPreloadedExamples(); i++ )
  912. {
  913. pb.update ( imageNetTest.getNumPreloadedExamples() );
  914. const SparseVector & svec = imageNetTest.getPreloadedExample ( i );
  915. //NOTE: again we should use method-specific optimal parameters. If we're only interested in the runtimes, this doesn't matter
  916. //compute (self) similarities
  917. double kernelSelf (measureDistance(svec,svec, kernelSigmaGPVarApprox) );
  918. NICE::Vector kernelVector (nrOfExamplesPerClass, 0.0);
  919. for (int j = 0; j < nrOfExamplesPerClass; j++)
  920. {
  921. kernelVector[j] = measureDistance(trainingData[j+cl*100],svec, kernelSigmaGPVarApprox);
  922. }
  923. //call the individual test-methods
  924. //evaluate GP Var Approx
  925. ClassificationResult rGPVarApprox;
  926. if (GPVarApprox)
  927. evaluateGPVarApprox( kernelVector, kernelSelf, matrixDInv, rGPVarApprox, timeForSingleExamplesGPVarApprox, runsPerClassToAverageTesting );
  928. //evaluate GP Var
  929. ClassificationResult rGPVar;
  930. if (GPVar)
  931. evaluateGPVar( kernelVector, kernelSelf, GPVarCholesky, rGPVar, timeForSingleExamplesGPVar, runsPerClassToAverageTesting );
  932. //evaluate GP Mean Approx
  933. ClassificationResult rGPMeanApprox;
  934. if (GPMeanApprox)
  935. evaluateGPMeanApprox( kernelVector, matrixDInv, rGPMeanApprox, timeForSingleExamplesGPMeanApprox, runsPerClassToAverageTesting );
  936. //evaluate GP Mean
  937. ClassificationResult rGPMean;
  938. if (GPMean)
  939. evaluateGPMean( kernelVector, GPMeanRightPart, rGPMean, timeForSingleExamplesGPMean, runsPerClassToAverageTesting );
  940. //evaluate GP SR Mean
  941. ClassificationResult rGPSRMean;
  942. if (GPSRMean)
  943. evaluateGPSRMean( kernelVector, GPSRMeanRightPart, rGPSRMean, timeForSingleExamplesGPSRMean, runsPerClassToAverageTesting, nrOfRegressors, indicesOfChosenExamplesGPSRMean );
  944. //evaluate GP SR Var
  945. ClassificationResult rGPSRVar;
  946. if (GPSRVar)
  947. evaluateGPSRVar( kernelVector, GPSRVarCholesky, rGPSRVar, timeForSingleExamplesGPSRVar, runsPerClassToAverageTesting, nrOfRegressors, indicesOfChosenExamplesGPSRVar, noiseGPSRVarParas[cl] );
  948. //evaluate GP Opt Mean
  949. ClassificationResult rGPOptMean;
  950. if (GPOptMean)
  951. evaluateGPOptMean( kernelVector, GPOptMeanRightPart, rGPOptMean, timeForSingleExamplesGPOptMean, runsPerClassToAverageTesting );
  952. //evaluate GP Opt Var
  953. ClassificationResult rGPOptVar;
  954. if (GPOptVar)
  955. evaluateGPOptVar( kernelVector, kernelSelf, DiagGPOptVar, rGPOptVar, timeForSingleExamplesGPOptVar, runsPerClassToAverageTesting );
  956. //evaluate Parzen
  957. ClassificationResult rParzen;
  958. if (Parzen)
  959. evaluateParzen( kernelVector, rParzen, timeForSingleExamplesParzen, runsPerClassToAverageTesting );
  960. //evaluate SVDD
  961. ClassificationResult rSVDD;
  962. if (SVDD)
  963. evaluateSVDD( svdd, kernelVector, rSVDD, timeForSingleExamplesSVDD, runsPerClassToAverageTesting );
  964. // set ground truth label
  965. rGPVarApprox.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  966. rGPVar.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  967. rGPMeanApprox.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  968. rGPMean.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  969. rGPSRMean.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  970. rGPSRVar.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  971. rGPOptMean.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  972. rGPOptVar.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  973. rParzen.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  974. rSVDD.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  975. //remember the results for the evaluation lateron
  976. resultsGPVarApprox.push_back ( rGPVarApprox );
  977. resultsGPVar.push_back ( rGPVar );
  978. resultsGPMeanApprox.push_back ( rGPMeanApprox );
  979. resultsGPMean.push_back ( rGPMean );
  980. resultsGPSRMean.push_back ( rGPSRMean );
  981. resultsGPSRVar.push_back ( rGPSRVar );
  982. resultsGPOptMean.push_back ( rGPOptMean );
  983. resultsGPOptVar.push_back ( rGPOptVar );
  984. resultsParzen.push_back ( rParzen );
  985. resultsSVDD.push_back ( rSVDD );
  986. }
  987. tTest.stop();
  988. std::cerr << "Time used for evaluating class " << cl << ": " << tTest.getLast() << std::endl;
  989. timeForSingleExamplesGPVarApprox/= imageNetTest.getNumPreloadedExamples();
  990. timeForSingleExamplesGPVar/= imageNetTest.getNumPreloadedExamples();
  991. timeForSingleExamplesGPMeanApprox/= imageNetTest.getNumPreloadedExamples();
  992. timeForSingleExamplesGPMean/= imageNetTest.getNumPreloadedExamples();
  993. timeForSingleExamplesGPSRMean/= imageNetTest.getNumPreloadedExamples();
  994. timeForSingleExamplesGPSRVar/= imageNetTest.getNumPreloadedExamples();
  995. timeForSingleExamplesGPOptMean/= imageNetTest.getNumPreloadedExamples();
  996. timeForSingleExamplesGPOptVar/= imageNetTest.getNumPreloadedExamples();
  997. timeForSingleExamplesParzen/= imageNetTest.getNumPreloadedExamples();
  998. timeForSingleExamplesSVDD/= imageNetTest.getNumPreloadedExamples();
  999. std::cerr << "GPVarApprox -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPVarApprox << std::endl;
  1000. std::cerr << "GPVar -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPVar << std::endl;
  1001. std::cerr << "GPMeanApprox -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPMeanApprox << std::endl;
  1002. std::cerr << "GPMean -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPMean << std::endl;
  1003. std::cerr << "GPSRMean -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPSRMean << std::endl;
  1004. std::cerr << "GPSRVar -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPSRVar << std::endl;
  1005. std::cerr << "GPOptMean -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPOptMean << std::endl;
  1006. std::cerr << "GPOptVar -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPOptVar << std::endl;
  1007. std::cerr << "Parzen -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesParzen << std::endl;
  1008. std::cerr << "SVDD -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesSVDD << std::endl;
  1009. // run the AUC-evaluation
  1010. double perfvalueGPVarApprox( 0.0 );
  1011. double perfvalueGPVar( 0.0 );
  1012. double perfvalueGPMeanApprox( 0.0 );
  1013. double perfvalueGPMean( 0.0 );
  1014. double perfvalueGPSRMean( 0.0 );
  1015. double perfvalueGPSRVar( 0.0 );
  1016. double perfvalueGPOptMean( 0.0 );
  1017. double perfvalueGPOptVar( 0.0 );
  1018. double perfvalueParzen( 0.0 );
  1019. double perfvalueSVDD( 0.0 );
  1020. if (GPVarApprox)
  1021. perfvalueGPVarApprox = resultsGPVarApprox.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1022. if (GPVar)
  1023. perfvalueGPVar = resultsGPVar.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1024. if (GPMeanApprox)
  1025. perfvalueGPMeanApprox = resultsGPMeanApprox.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1026. if (GPMean)
  1027. perfvalueGPMean = resultsGPMean.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1028. if (GPSRMean)
  1029. perfvalueGPSRMean = resultsGPSRMean.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1030. if (GPSRVar)
  1031. perfvalueGPSRVar = resultsGPSRVar.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1032. if (GPOptMean)
  1033. perfvalueGPOptMean = resultsGPOptMean.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1034. if (GPOptVar)
  1035. perfvalueGPOptVar = resultsGPOptVar.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1036. if (Parzen)
  1037. perfvalueParzen = resultsParzen.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1038. if (SVDD)
  1039. perfvalueSVDD = resultsSVDD.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1040. std::cerr << "Performance GPVarApprox: " << perfvalueGPVarApprox << std::endl;
  1041. std::cerr << "Performance GPVar: " << perfvalueGPVar << std::endl;
  1042. std::cerr << "Performance GPMeanApprox: " << perfvalueGPMeanApprox << std::endl;
  1043. std::cerr << "Performance GPMean: " << perfvalueGPMean << std::endl;
  1044. std::cerr << "Performance GPSRMean: " << perfvalueGPSRMean << std::endl;
  1045. std::cerr << "Performance GPSRVar: " << perfvalueGPSRVar << std::endl;
  1046. std::cerr << "Performance GPOptMean: " << perfvalueGPOptMean << std::endl;
  1047. std::cerr << "Performance GPOptVar: " << perfvalueGPOptVar << std::endl;
  1048. std::cerr << "Performance Parzen: " << perfvalueParzen << std::endl;
  1049. std::cerr << "Performance SVDD: " << perfvalueSVDD << std::endl;
  1050. OverallPerformanceGPVarApprox += perfvalueGPVar;
  1051. OverallPerformanceGPVar += perfvalueGPVarApprox;
  1052. OverallPerformanceGPMeanApprox += perfvalueGPMeanApprox;
  1053. OverallPerformanceGPMean += perfvalueGPMean;
  1054. OverallPerformanceGPSRMean += perfvalueGPSRMean;
  1055. OverallPerformanceGPSRVar += perfvalueGPSRVar;
  1056. OverallPerformanceGPOptMean += perfvalueGPOptMean;
  1057. OverallPerformanceGPOptVar += perfvalueGPOptVar;
  1058. OverallPerformanceParzen += perfvalueParzen;
  1059. OverallPerformanceSVDD += perfvalueSVDD;
  1060. // clean up memory used by SVDD
  1061. if (SVDD)
  1062. delete svdd;
  1063. }
  1064. OverallPerformanceGPVarApprox /= nrOfClassesToConcidere;
  1065. OverallPerformanceGPVar /= nrOfClassesToConcidere;
  1066. OverallPerformanceGPMeanApprox /= nrOfClassesToConcidere;
  1067. OverallPerformanceGPMean /= nrOfClassesToConcidere;
  1068. OverallPerformanceGPSRMean /= nrOfClassesToConcidere;
  1069. OverallPerformanceGPSRVar /= nrOfClassesToConcidere;
  1070. OverallPerformanceGPOptMean /= nrOfClassesToConcidere;
  1071. OverallPerformanceGPOptVar /= nrOfClassesToConcidere;
  1072. OverallPerformanceParzen /= nrOfClassesToConcidere;
  1073. OverallPerformanceSVDD /= nrOfClassesToConcidere;
  1074. std::cerr << "overall performance GPVarApprox: " << OverallPerformanceGPVarApprox << std::endl;
  1075. std::cerr << "overall performance GPVar: " << OverallPerformanceGPVar << std::endl;
  1076. std::cerr << "overall performance GPMeanApprox: " << OverallPerformanceGPMeanApprox << std::endl;
  1077. std::cerr << "overall performance GPMean: " << OverallPerformanceGPMean << std::endl;
  1078. std::cerr << "overall performance GPSRMean: " << OverallPerformanceGPSRMean << std::endl;
  1079. std::cerr << "overall performance GPSRVar: " << OverallPerformanceGPSRVar << std::endl;
  1080. std::cerr << "overall performance GPOptMean: " << OverallPerformanceGPOptMean << std::endl;
  1081. std::cerr << "overall performance GPOptVar: " << OverallPerformanceGPOptVar << std::endl;
  1082. std::cerr << "overall performance Parzen: " << OverallPerformanceParzen << std::endl;
  1083. std::cerr << "overall performance SVDD: " << OverallPerformanceSVDD << std::endl;
  1084. return 0;
  1085. }