testImageNetBinaryBruteForce.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  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/vector/Algorithms.h"
  13. #include "core/vector/SparseVectorT.h"
  14. #include "vislearning/cbaselib/ClassificationResults.h"
  15. #include "vislearning/baselib/ProgressBar.h"
  16. #include "vislearning/classifier/kernelclassifier/KCMinimumEnclosingBall.h"
  17. #include "fast-hik/tools.h"
  18. #include "fast-hik/MatFileIO.h"
  19. #include "fast-hik/ImageNetData.h"
  20. using namespace std;
  21. using namespace NICE;
  22. using namespace OBJREC;
  23. // --------------- THE KERNEL FUNCTION ( exponential kernel with euclidian distance ) ----------------------
  24. double measureDistance ( const NICE::SparseVector & a, const NICE::SparseVector & b, const double & sigma = 2.0)//, const bool & verbose = false)
  25. {
  26. double inner_sum(0.0);
  27. double d;
  28. //new version, where we needed on average 0.001707 s for each test sample
  29. NICE::SparseVector::const_iterator aIt = a.begin();
  30. NICE::SparseVector::const_iterator bIt = b.begin();
  31. while ( (aIt != a.end()) && (bIt != b.end()) )
  32. {
  33. if (aIt->first == bIt->first)
  34. {
  35. d = ( aIt->second - bIt->second );
  36. inner_sum += d * d;
  37. aIt++;
  38. bIt++;
  39. }
  40. else if ( aIt->first < bIt->first)
  41. {
  42. inner_sum += aIt->second * aIt->second;
  43. aIt++;
  44. }
  45. else
  46. {
  47. inner_sum += bIt->second * bIt->second;
  48. bIt++;
  49. }
  50. }
  51. //compute remaining values, if b reached the end but not a
  52. while (aIt != a.end())
  53. {
  54. inner_sum += aIt->second * aIt->second;
  55. aIt++;
  56. }
  57. //compute remaining values, if a reached the end but not b
  58. while (bIt != b.end())
  59. {
  60. inner_sum += bIt->second * bIt->second;
  61. bIt++;
  62. }
  63. inner_sum /= (2.0*sigma*sigma);
  64. return exp(-inner_sum);
  65. }
  66. void readParameters(const string & filename, const int & size, NICE::Vector & parameterVector)
  67. {
  68. parameterVector.resize(size);
  69. parameterVector.set(0.0);
  70. ifstream is(filename.c_str());
  71. if ( !is.good() )
  72. fthrow(IOException, "Unable to read parameters.");
  73. //
  74. string tmp;
  75. int cnt(0);
  76. while (! is.eof())
  77. {
  78. is >> tmp;
  79. parameterVector[cnt] = atof(tmp.c_str());
  80. cnt++;
  81. }
  82. //
  83. is.close();
  84. }
  85. //------------------- TRAINING METHODS --------------------
  86. void inline trainGPVarApprox(NICE::Vector & matrixDInv, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber)
  87. {
  88. std::cerr << "nrOfExamplesPerClass : " << nrOfExamplesPerClass << std::endl;
  89. Timer tTrainPreciseTimer;
  90. tTrainPreciseTimer.start();
  91. // time_t time;
  92. // std::cerr <<
  93. std::cerr << time(NULL) << std::endl;
  94. //tic tTrainPrecise
  95. clock_t tTrainPreciseStart = clock() * CLOCKS_PER_SEC;
  96. usleep(35);
  97. matrixDInv.resize(nrOfExamplesPerClass);
  98. matrixDInv.set(0.0);
  99. //compute D
  100. //start with adding some noise, if necessary
  101. if (noise != 0.0)
  102. matrixDInv.set(noise);
  103. else
  104. matrixDInv.set(0.0);
  105. for (int i = 0; i < nrOfExamplesPerClass; i++)
  106. {
  107. for (int j = i; j < nrOfExamplesPerClass; j++)
  108. {
  109. matrixDInv[i] += kernelMatrix(i,j);
  110. if (i != j)
  111. matrixDInv[j] += kernelMatrix(i,j);
  112. }
  113. }
  114. //compute its inverse
  115. for (int i = 0; i < nrOfExamplesPerClass; i++)
  116. {
  117. matrixDInv[i] = 1.0 / matrixDInv[i];
  118. }
  119. tTrainPreciseTimer.stop();
  120. std::cerr << "Precise time used for training class " << classNumber << ": " << tTrainPreciseTimer.getLast() << std::endl;
  121. //toc tTrainPrecise
  122. clock_t currentTime = clock() * CLOCKS_PER_SEC;
  123. float tTrainPrecise = (float) (currentTime - tTrainPreciseStart);
  124. std::cerr << "start time: " << tTrainPreciseStart << std::endl;
  125. std::cerr << "current time: " << currentTime << std::endl;
  126. std::cerr << "Precise time used for GPVarApprox training class " << classNumber << ": " << currentTime-tTrainPreciseStart << std::endl;
  127. std::cerr << "final time in system clock whatever:" << std::endl;
  128. std::cerr << time(NULL) << std::endl;
  129. }
  130. void inline trainGPVar(NICE::Matrix & choleskyMatrix, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber)
  131. {
  132. /* Timer tTrainPrecise;
  133. tTrainPrecise.start(); */
  134. //tic tTrainPrecise
  135. time_t tTrainPreciseStart = clock();
  136. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  137. choleskyMatrix.resize(nrOfExamplesPerClass, nrOfExamplesPerClass);
  138. choleskyMatrix.set(0.0);
  139. cr.robustChol ( kernelMatrix, choleskyMatrix );
  140. // tTrainPrecise.stop();
  141. // std::cerr << "Precise time used for training class " << classNumber << ": " << tTrainPrecise.getLast() << std::endl;
  142. //toc tTrainPrecise
  143. time_t currentTime = clock();
  144. float tTrainPrecise = (float) (currentTime - tTrainPreciseStart);
  145. std::cerr << "start time: " << tTrainPreciseStart << std::endl;
  146. std::cerr << "current time: " << currentTime << std::endl;
  147. std::cerr << "Precise time used for GPVar training class " << classNumber << ": " << tTrainPrecise/CLOCKS_PER_SEC << std::endl;
  148. }
  149. void inline trainGPMeanApprox(NICE::Vector & GPMeanApproxRightPart, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber)
  150. {
  151. /* Timer tTrainPrecise;
  152. tTrainPrecise.start(); */
  153. //tic tTrainPrecise
  154. time_t tTrainPreciseStart = clock();
  155. NICE::Vector matrixDInv(nrOfExamplesPerClass,0.0);
  156. //compute D
  157. //start with adding some noise, if necessary
  158. if (noise != 0.0)
  159. matrixDInv.set(noise);
  160. else
  161. matrixDInv.set(0.0);
  162. for (int i = 0; i < nrOfExamplesPerClass; i++)
  163. {
  164. for (int j = i; j < nrOfExamplesPerClass; j++)
  165. {
  166. matrixDInv[i] += kernelMatrix(i,j);
  167. if (i != j)
  168. matrixDInv[j] += kernelMatrix(i,j);
  169. }
  170. }
  171. //compute its inverse (and multiply every element with the label vector, which contains only one-entries...)
  172. GPMeanApproxRightPart.resize(nrOfExamplesPerClass);
  173. for (int i = 0; i < nrOfExamplesPerClass; i++)
  174. {
  175. GPMeanApproxRightPart[i] = 1.0 / matrixDInv[i];
  176. }
  177. // tTrainPrecise.stop();
  178. // std::cerr << "Precise time used for training class " << classNumber << ": " << tTrainPrecise.getLast() << std::endl;
  179. //toc tTrainPrecise
  180. time_t currentTime = clock();
  181. float tTrainPrecise = (float) (currentTime - tTrainPreciseStart);
  182. std::cerr << "start time: " << tTrainPreciseStart << std::endl;
  183. std::cerr << "current time: " << currentTime << std::endl;
  184. std::cerr << "Precise time used for GPMeanApprox training class " << classNumber << ": " << tTrainPrecise/CLOCKS_PER_SEC << std::endl;
  185. }
  186. void inline trainGPMean(NICE::Vector & GPMeanRightPart, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber)
  187. {
  188. /* Timer tTrainPrecise;
  189. tTrainPrecise.start(); */
  190. //tic tTrainPrecise
  191. time_t tTrainPreciseStart = clock();
  192. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  193. NICE::Matrix choleskyMatrix (nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0);
  194. cr.robustChol ( kernelMatrix, choleskyMatrix );
  195. GPMeanRightPart.resize(nrOfExamplesPerClass);
  196. GPMeanRightPart.set(0.0);
  197. NICE::Vector y(nrOfExamplesPerClass,1.0); //OCC setting :)
  198. choleskySolveLargeScale ( choleskyMatrix, y, GPMeanRightPart );
  199. // tTrainPrecise.stop();
  200. // std::cerr << "Precise time used for training class " << classNumber << ": " << tTrainPrecise.getLast() << std::endl;
  201. //toc tTrainPrecise
  202. time_t currentTime = clock();
  203. float tTrainPrecise = (float) (currentTime - tTrainPreciseStart);
  204. std::cerr << "start time: " << tTrainPreciseStart << std::endl;
  205. std::cerr << "current time: " << currentTime << std::endl;
  206. std::cerr << "Precise time used for GPMean training class " << classNumber << ": " << tTrainPrecise/CLOCKS_PER_SEC << std::endl;
  207. }
  208. KCMinimumEnclosingBall *trainSVDD( const double & noise, const NICE::Matrix kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber)
  209. {
  210. Config conf;
  211. // set the outlier ratio (Paul optimized this paramter FIXME)
  212. conf.sD( "SVDD", "outlier_fraction", 0.1 );
  213. KCMinimumEnclosingBall *svdd = new KCMinimumEnclosingBall ( &conf, NULL /* no kernel function */, "SVDD" /* config section */, false /* update cholesky */ );
  214. KernelData kernelData ( &conf, kernelMatrix, "Kernel" );
  215. /* Timer tTrainPrecise;
  216. tTrainPrecise.start(); */
  217. //tic tTrainPrecise
  218. time_t tTrainPreciseStart = clock();
  219. // tTrainPrecise.stop();
  220. // std::cerr << "Precise time used for training class " << classNumber << ": " << tTrainPrecise.getLast() << std::endl;
  221. //toc tTrainPrecise
  222. time_t currentTime = clock();
  223. float tTrainPrecise = (float) (currentTime - tTrainPreciseStart);
  224. NICE::Vector y(nrOfExamplesPerClass,1.0); //OCC setting :)
  225. // KCMinimumEnclosingBall does not store the kernel data object, therefore, we are save with passing a local copy
  226. svdd->teach ( &kernelData, y );
  227. std::cerr << "start time: " << tTrainPreciseStart << std::endl;
  228. std::cerr << "current time: " << currentTime << std::endl;
  229. std::cerr << "Precise time used for SVDD training class " << classNumber << ": " << tTrainPrecise/CLOCKS_PER_SEC << std::endl;
  230. return svdd;
  231. }
  232. // ------------- EVALUATION METHODS ---------------------
  233. void inline evaluateGPVarApprox(const NICE::Vector & kernelVector, const double & kernelSelf, const NICE::Vector & matrixDInv, ClassificationResult & r, double & timeForSingleExamples)
  234. {
  235. Timer tTestSingle;
  236. tTestSingle.start();
  237. NICE::Vector rightPart (kernelVector.size());
  238. for (int j = 0; j < kernelVector.size(); j++)
  239. {
  240. rightPart[j] = kernelVector[j] * matrixDInv[j];
  241. }
  242. double uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  243. tTestSingle.stop();
  244. timeForSingleExamples += tTestSingle.getLast();
  245. FullVector scores ( 2 );
  246. scores[0] = 0.0;
  247. scores[1] = 1.0 - uncertainty;
  248. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  249. }
  250. void inline evaluateGPVar(const NICE::Vector & kernelVector, const double & kernelSelf, const NICE::Matrix & choleskyMatrix, ClassificationResult & r, double & timeForSingleExamples)
  251. {
  252. Timer tTestSingle;
  253. tTestSingle.start();
  254. NICE::Vector rightPart (kernelVector.size(),0.0);
  255. choleskySolveLargeScale ( choleskyMatrix, kernelVector, rightPart );
  256. double uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  257. tTestSingle.stop();
  258. timeForSingleExamples += tTestSingle.getLast();
  259. FullVector scores ( 2 );
  260. scores[0] = 0.0;
  261. scores[1] = 1.0 - uncertainty;
  262. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  263. }
  264. void inline evaluateGPMeanApprox(const NICE::Vector & kernelVector, const NICE::Vector & rightPart, ClassificationResult & r, double & timeForSingleExamples)
  265. {
  266. Timer tTestSingle;
  267. tTestSingle.start();
  268. double mean = kernelVector.scalarProduct ( rightPart );
  269. tTestSingle.stop();
  270. timeForSingleExamples += tTestSingle.getLast();
  271. FullVector scores ( 2 );
  272. scores[0] = 0.0;
  273. scores[1] = mean;
  274. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  275. }
  276. void inline evaluateGPMean(const NICE::Vector & kernelVector, const NICE::Vector & GPMeanRightPart, ClassificationResult & r, double & timeForSingleExamples)
  277. {
  278. Timer tTestSingle;
  279. tTestSingle.start();
  280. double mean = kernelVector.scalarProduct ( GPMeanRightPart );
  281. tTestSingle.stop();
  282. timeForSingleExamples += tTestSingle.getLast();
  283. FullVector scores ( 2 );
  284. scores[0] = 0.0;
  285. scores[1] = mean;
  286. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  287. }
  288. void inline evaluateParzen(const NICE::Vector & kernelVector, ClassificationResult & r, double & timeForSingleExamples)
  289. {
  290. Timer tTestSingle;
  291. tTestSingle.start();
  292. double score( kernelVector.Sum() / (double) kernelVector.size() ); //maybe we could directly call kernelVector.Mean()
  293. tTestSingle.stop();
  294. timeForSingleExamples += tTestSingle.getLast();
  295. FullVector scores ( 2 );
  296. scores[0] = 0.0;
  297. scores[1] = score;
  298. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  299. }
  300. void inline evaluateSVDD( KCMinimumEnclosingBall *svdd, const NICE::Vector & kernelVector, ClassificationResult & r, double & timeForSingleExamples)
  301. {
  302. Timer tTestSingle;
  303. tTestSingle.start();
  304. // In the following, we assume that we are using a Gaussian kernel
  305. r = svdd->classifyKernel ( kernelVector, 1.0 /* kernel self */ );
  306. tTestSingle.stop();
  307. timeForSingleExamples += tTestSingle.getLast();
  308. }
  309. /**
  310. test the basic functionality of fast-hik hyperparameter optimization
  311. */
  312. int main (int argc, char **argv)
  313. {
  314. std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
  315. Config conf ( argc, argv );
  316. string resultsfile = conf.gS("main", "results", "results.txt" );
  317. int nrOfExamplesPerClass = conf.gI("main", "nrOfExamplesPerClass", 50);
  318. nrOfExamplesPerClass = std::min(nrOfExamplesPerClass, 100); // we do not have more than 100 examples per class
  319. int indexOfFirstClass = conf.gI("main", "indexOfFirstClass", 0);
  320. indexOfFirstClass = std::max(indexOfFirstClass, 0); //we do not have less than 0 classes
  321. int indexOfLastClass = conf.gI("main", "indexOfLastClass", 999);
  322. indexOfLastClass = std::min(indexOfLastClass, 999); //we do not have more than 1000 classes
  323. int nrOfClassesToConcidere = (indexOfLastClass - indexOfLastClass)+1;
  324. //read the optimal parameters for the different methods
  325. // GP variance approximation
  326. string sigmaGPVarApproxFile = conf.gS("main", "sigmaGPVarApproxFile", "approxVarSigma.txt");
  327. string noiseGPVarApproxFile = conf.gS("main", "noiseGPVarApproxFile", "approxVarNoise.txt");
  328. // GP variance
  329. string sigmaGPVarFile = conf.gS("main", "sigmaGPVarFile", "approxVarSigma.txt");
  330. string noiseGPVarFile = conf.gS("main", "noiseGPVarFile", "approxVarNoise.txt");
  331. //GP mean approximation
  332. string sigmaGPMeanApproxFile = conf.gS("main", "sigmaGPMeanApproxFile", "approxVarSigma.txt");
  333. string noiseGPMeanApproxFile = conf.gS("main", "noiseGPMeanApproxFile", "approxVarNoise.txt");
  334. //GP mean
  335. string sigmaGPMeanFile = conf.gS("main", "sigmaGPMeanFile", "approxVarSigma.txt");
  336. string noiseGPMeanFile = conf.gS("main", "noiseGPMeanFile", "approxVarNoise.txt");
  337. //Parzen
  338. string sigmaParzenFile = conf.gS("main", "sigmaParzenFile", "approxVarSigma.txt");
  339. string noiseParzenFile = conf.gS("main", "noiseParzenFile", "approxVarNoise.txt");
  340. //SVDD
  341. string sigmaSVDDFile = conf.gS("main", "sigmaSVDDFile", "approxVarSigma.txt");
  342. string noiseSVDDFile = conf.gS("main", "noiseSVDDFile", "approxVarNoise.txt");
  343. // GP variance approximation
  344. NICE::Vector sigmaGPVarApproxParas(nrOfClassesToConcidere,0.0);
  345. NICE::Vector noiseGPVarApproxParas(nrOfClassesToConcidere,0.0);
  346. // GP variance
  347. NICE::Vector sigmaGPVarParas(nrOfClassesToConcidere,0.0);
  348. NICE::Vector noiseGPVarParas(nrOfClassesToConcidere,0.0);
  349. //GP mean approximation
  350. NICE::Vector sigmaGPMeanApproxParas(nrOfClassesToConcidere,0.0);
  351. NICE::Vector noiseGPMeanApproxParas(nrOfClassesToConcidere,0.0);
  352. //GP mean
  353. NICE::Vector sigmaGPMeanParas(nrOfClassesToConcidere,0.0);
  354. NICE::Vector noiseGPMeanParas(nrOfClassesToConcidere,0.0);
  355. //Parzen
  356. NICE::Vector sigmaParzenParas(nrOfClassesToConcidere,0.0);
  357. NICE::Vector noiseParzenParas(nrOfClassesToConcidere,0.0);
  358. //SVDD
  359. NICE::Vector sigmaSVDDParas(nrOfClassesToConcidere,0.0);
  360. NICE::Vector noiseSVDDParas(nrOfClassesToConcidere,0.0);
  361. // GP variance approximation
  362. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPVarApproxParas);
  363. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPVarApproxParas);
  364. // GP variance
  365. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPVarParas);
  366. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPVarParas);
  367. //GP mean approximation
  368. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPMeanApproxParas);
  369. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPMeanApproxParas);
  370. //GP mean
  371. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPMeanParas);
  372. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPMeanParas);
  373. //Parzen
  374. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaParzenParas);
  375. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseParzenParas);
  376. //SVDD
  377. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaSVDDParas);
  378. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseSVDDParas);
  379. // -------- optimal parameters read --------------
  380. std::vector<SparseVector> trainingData;
  381. NICE::Vector y;
  382. std::cerr << "Reading ImageNet data ..." << std::endl;
  383. bool imageNetLocal = conf.gB("main", "imageNetLocal" , false);
  384. string imageNetPath;
  385. if (imageNetLocal)
  386. imageNetPath = "/users2/rodner/data/imagenet/devkit-1.0/";
  387. else
  388. imageNetPath = "/home/dbv/bilder/imagenet/devkit-1.0/";
  389. ImageNetData imageNetTrain ( imageNetPath + "demo/" );
  390. imageNetTrain.preloadData( "train", "training" );
  391. trainingData = imageNetTrain.getPreloadedData();
  392. y = imageNetTrain.getPreloadedLabels();
  393. std::cerr << "Reading of training data finished" << std::endl;
  394. std::cerr << "trainingData.size(): " << trainingData.size() << std::endl;
  395. std::cerr << "y.size(): " << y.size() << std::endl;
  396. std::cerr << "Reading ImageNet test data files (takes some seconds)..." << std::endl;
  397. ImageNetData imageNetTest ( imageNetPath + "demo/" );
  398. imageNetTest.preloadData ( "val", "testing" );
  399. imageNetTest.loadExternalLabels ( imageNetPath + "data/ILSVRC2010_validation_ground_truth.txt" );
  400. double OverallPerformanceGPVarApprox(0.0);
  401. double OverallPerformanceGPVar(0.0);
  402. double OverallPerformanceGPMeanApprox(0.0);
  403. double OverallPerformanceGPMean(0.0);
  404. double OverallPerformanceParzen(0.0);
  405. double OverallPerformanceSVDD(0.0);
  406. double kernelSigmaGPVarApprox;
  407. double kernelSigmaGPVar;
  408. double kernelSigmaGPMeanApprox;
  409. double kernelSigmaGPMean;
  410. double kernelSigmaParzen;
  411. double kernelSigmaSVDD;
  412. for (int cl = indexOfFirstClass; cl < indexOfLastClass; cl++)
  413. {
  414. std::cerr << "run for class " << cl << std::endl;
  415. int positiveClass = cl+1; //labels are from 1 to 1000, but our indices from 0 to 999
  416. // ------------------------------ TRAINING ------------------------------
  417. kernelSigmaGPVarApprox = sigmaGPVarApproxParas[cl];
  418. kernelSigmaGPVar = sigmaGPVarParas[cl];
  419. kernelSigmaGPMeanApprox = sigmaGPMeanApproxParas[cl];
  420. kernelSigmaGPMean = sigmaGPMeanParas[cl];
  421. kernelSigmaParzen = sigmaParzenParas[cl];
  422. kernelSigmaSVDD = sigmaSVDDParas[cl];
  423. Timer tTrain;
  424. tTrain.start();
  425. NICE::Matrix kernelMatrix(nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0);
  426. //TODO in theory we have to compute a single kernel Matrix for every method, since every method may have its own optimal parameter
  427. // I'm sure, we can speed it up a bit and compute it only for every different parameter
  428. //nonetheless, it's not as nice as we originally thought (same matrix for every method)
  429. //NOTE since we're only interested in runtimes, we can ignore this (and still do some further code optimization...) //TODO
  430. /* //adding some noise, if necessary
  431. if (noiseParas[cl] != 0.0)
  432. {
  433. kernelMatrix.addIdentity(noiseParas[cl]);
  434. }
  435. else
  436. {
  437. //zero was already set
  438. } */
  439. //now sum up all entries of each row in the original kernel matrix
  440. double kernelScore(0.0);
  441. for (int i = cl*100; i < cl*100+nrOfExamplesPerClass; i++)
  442. {
  443. for (int j = i; j < cl*100+nrOfExamplesPerClass; j++)
  444. {
  445. kernelScore = measureDistance(trainingData[i],trainingData[j], kernelSigmaGPVarApprox);
  446. kernelMatrix(i-cl*100,j-cl*100) = kernelScore;
  447. if (i != j)
  448. kernelMatrix(j-cl*100,i-cl*100) = kernelScore;
  449. }
  450. }
  451. //train GP Var Approx
  452. NICE::Vector matrixDInv;
  453. trainGPVarApprox(matrixDInv, noiseGPVarApproxParas[cl], kernelMatrix, nrOfExamplesPerClass, cl);
  454. //train GP Var
  455. NICE::Matrix GPVarCholesky;
  456. trainGPVar(GPVarCholesky, noiseGPVarParas[cl], kernelMatrix, nrOfExamplesPerClass, cl);
  457. //train GP Mean Approx
  458. NICE::Vector GPMeanApproxRightPart;
  459. trainGPMeanApprox(GPMeanApproxRightPart, noiseGPMeanApproxParas[cl], kernelMatrix, nrOfExamplesPerClass, cl);
  460. //train GP Mean
  461. NICE::Vector GPMeanRightPart;
  462. trainGPMean(GPMeanRightPart, noiseGPMeanParas[cl], kernelMatrix, nrOfExamplesPerClass, cl);
  463. //train Parzen
  464. //nothing to do :)
  465. //train SVDD
  466. //TODO what do we need here?
  467. KCMinimumEnclosingBall *svdd = trainSVDD(noiseSVDDParas[cl], kernelMatrix, nrOfExamplesPerClass, cl);
  468. tTrain.stop();
  469. std::cerr << "Time used for training class " << cl << ": " << tTrain.getLast() << std::endl;
  470. std::cerr << "training done - now perform the evaluation" << std::endl;
  471. // ------------------------------ TESTING ------------------------------
  472. std::cerr << "Classification step ... with " << imageNetTest.getNumPreloadedExamples() << " examples" << std::endl;
  473. ClassificationResults resultsGPVarApprox;
  474. ClassificationResults resultsGPVar;
  475. ClassificationResults resultsGPMeanApprox;
  476. ClassificationResults resultsGPMean;
  477. ClassificationResults resultsParzen;
  478. ClassificationResults resultsSVDD;
  479. ProgressBar pb;
  480. Timer tTest;
  481. tTest.start();
  482. Timer tTestSingle;
  483. double timeForSingleExamplesGPVarApprox(0.0);
  484. double timeForSingleExamplesGPVar(0.0);
  485. double timeForSingleExamplesGPMeanApprox(0.0);
  486. double timeForSingleExamplesGPMean(0.0);
  487. double timeForSingleExamplesParzen(0.0);
  488. double timeForSingleExamplesSVDD(0.0);
  489. for ( uint i = 0 ; i < (uint)imageNetTest.getNumPreloadedExamples(); i++ )
  490. {
  491. pb.update ( imageNetTest.getNumPreloadedExamples() );
  492. const SparseVector & svec = imageNetTest.getPreloadedExample ( i );
  493. //TODO: again we should use method-specific optimal parameters. If we're only interested in the runtimes, this doesn't matter
  494. double kernelSelf (measureDistance(svec,svec, kernelSigmaGPVarApprox) );
  495. NICE::Vector kernelVector (nrOfExamplesPerClass, 0.0);
  496. for (int j = 0; j < nrOfExamplesPerClass; j++)
  497. {
  498. kernelVector[j] = measureDistance(trainingData[j+cl*100],svec, kernelSigmaGPVarApprox);
  499. }
  500. //evaluate GP Var Approx
  501. ClassificationResult rGPVarApprox;
  502. evaluateGPVarApprox(kernelVector, kernelSelf, matrixDInv, rGPVarApprox, timeForSingleExamplesGPVarApprox);
  503. //evaluate GP Var
  504. ClassificationResult rGPVar;
  505. evaluateGPVar(kernelVector, kernelSelf, GPVarCholesky, rGPVar, timeForSingleExamplesGPVar);
  506. //evaluate GP Mean Approx
  507. ClassificationResult rGPMeanApprox;
  508. evaluateGPMeanApprox(kernelVector, matrixDInv, rGPMeanApprox, timeForSingleExamplesGPMeanApprox);
  509. //evaluate GP Mean
  510. ClassificationResult rGPMean;
  511. evaluateGPMean(kernelVector, GPMeanRightPart, rGPMean, timeForSingleExamplesGPMean);
  512. //evaluate Parzen
  513. ClassificationResult rParzen;
  514. evaluateParzen(kernelVector, rParzen, timeForSingleExamplesParzen);
  515. //evaluate SVDD
  516. ClassificationResult rSVDD;
  517. evaluateSVDD(svdd, kernelVector, rSVDD, timeForSingleExamplesSVDD);
  518. // set ground truth label
  519. rGPVarApprox.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  520. rGPVar.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  521. rGPMeanApprox.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  522. rGPMean.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  523. rParzen.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  524. rSVDD.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  525. // std::cerr << "scores: " << std::endl;
  526. // scores >> std::cerr;
  527. // std::cerr << "gt: " << r.classno_groundtruth << " -- " << r.classno << std::endl;
  528. resultsGPVarApprox.push_back ( rGPVarApprox );
  529. resultsGPVar.push_back ( rGPVar );
  530. resultsGPMeanApprox.push_back ( rGPMeanApprox );
  531. resultsGPMean.push_back ( rGPMean );
  532. resultsParzen.push_back ( rParzen );
  533. resultsSVDD.push_back ( rSVDD );
  534. }
  535. tTest.stop();
  536. std::cerr << "Time used for evaluating class " << cl << ": " << tTest.getLast() << std::endl;
  537. timeForSingleExamplesGPVarApprox/= imageNetTest.getNumPreloadedExamples();
  538. timeForSingleExamplesGPVar/= imageNetTest.getNumPreloadedExamples();
  539. timeForSingleExamplesGPMeanApprox/= imageNetTest.getNumPreloadedExamples();
  540. timeForSingleExamplesGPMean/= imageNetTest.getNumPreloadedExamples();
  541. timeForSingleExamplesParzen/= imageNetTest.getNumPreloadedExamples();
  542. timeForSingleExamplesSVDD/= imageNetTest.getNumPreloadedExamples();
  543. std::cerr << "GPVarApprox -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPVarApprox << std::endl;
  544. std::cerr << "GPVar -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPVar << std::endl;
  545. std::cerr << "GPMeanApprox -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPMeanApprox << std::endl;
  546. std::cerr << "GPMean -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPMean << std::endl;
  547. std::cerr << "Parzen -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesParzen << std::endl;
  548. std::cerr << "SVDD -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesSVDD << std::endl;
  549. // std::cerr << "Writing results to " << resultsfile << std::endl;
  550. // results.writeWEKA ( resultsfile, 1 );
  551. double perfvalueGPVarApprox = resultsGPVarApprox.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  552. double perfvalueGPVar = resultsGPVar.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  553. double perfvalueGPMeanApprox = resultsGPMeanApprox.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  554. double perfvalueGPMean = resultsGPMean.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  555. double perfvalueParzen = resultsParzen.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  556. double perfvalueSVDD = resultsSVDD.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  557. std::cerr << "Performance GPVarApprox: " << perfvalueGPVarApprox << std::endl;
  558. std::cerr << "Performance GPVar: " << perfvalueGPVar << std::endl;
  559. std::cerr << "Performance GPMeanApprox: " << perfvalueGPMeanApprox << std::endl;
  560. std::cerr << "Performance GPMean: " << perfvalueGPMean << std::endl;
  561. std::cerr << "Performance Parzen: " << perfvalueParzen << std::endl;
  562. std::cerr << "Performance SVDD: " << perfvalueSVDD << std::endl;
  563. OverallPerformanceGPVarApprox += perfvalueGPVar;
  564. OverallPerformanceGPVar += perfvalueGPVarApprox;
  565. OverallPerformanceGPMeanApprox += perfvalueGPMeanApprox;
  566. OverallPerformanceGPMean += perfvalueGPMean;
  567. OverallPerformanceParzen += perfvalueParzen;
  568. OverallPerformanceSVDD += perfvalueSVDD;
  569. // clean up memory used by SVDD
  570. delete svdd;
  571. }
  572. OverallPerformanceGPVarApprox /= nrOfClassesToConcidere;
  573. OverallPerformanceGPVar /= nrOfClassesToConcidere;
  574. OverallPerformanceGPMeanApprox /= nrOfClassesToConcidere;
  575. OverallPerformanceGPMean /= nrOfClassesToConcidere;
  576. OverallPerformanceParzen /= nrOfClassesToConcidere;
  577. OverallPerformanceSVDD /= nrOfClassesToConcidere;
  578. std::cerr << "overall performance GPVarApprox: " << OverallPerformanceGPVarApprox << std::endl;
  579. std::cerr << "overall performance GPVar: " << OverallPerformanceGPVar << std::endl;
  580. std::cerr << "overall performance GPMeanApprox: " << OverallPerformanceGPMeanApprox << std::endl;
  581. std::cerr << "overall performance GPMean: " << OverallPerformanceGPMean << std::endl;
  582. std::cerr << "overall performance Parzen: " << OverallPerformanceParzen << std::endl;
  583. std::cerr << "overall performance SVDD: " << OverallPerformanceSVDD << std::endl;
  584. return 0;
  585. }