testImageNetBinaryBruteForce.cpp 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336
  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 trainGPMean(NICE::Vector & GPMeanRightPart, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  93. {
  94. Timer tTrainPrecise;
  95. tTrainPrecise.start();
  96. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  97. {
  98. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  99. NICE::Matrix choleskyMatrix (nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0);
  100. //compute the cholesky decomposition of K in order to compute K^{-1} \cdot y
  101. cr.robustChol ( kernelMatrix, choleskyMatrix );
  102. GPMeanRightPart.resize(nrOfExamplesPerClass);
  103. GPMeanRightPart.set(0.0);
  104. NICE::Vector y(nrOfExamplesPerClass,1.0); //OCC setting :)
  105. // pre-compute K^{-1} \cdot y, which is the same for every new test sample
  106. choleskySolveLargeScale ( choleskyMatrix, y, GPMeanRightPart );
  107. }
  108. tTrainPrecise.stop();
  109. std::cerr << "Precise time used for GPMean training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  110. }
  111. void inline trainGPVar(NICE::Matrix & choleskyMatrix, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  112. {
  113. Timer tTrainPrecise;
  114. tTrainPrecise.start();
  115. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  116. {
  117. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  118. choleskyMatrix.resize(nrOfExamplesPerClass, nrOfExamplesPerClass);
  119. choleskyMatrix.set(0.0);
  120. //compute the cholesky decomposition of K in order to compute K^{-1} \cdot k_* for new test samples
  121. cr.robustChol ( kernelMatrix, choleskyMatrix );
  122. }
  123. tTrainPrecise.stop();
  124. std::cerr << "Precise time used for GPVar training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  125. }
  126. void inline trainGPMeanApprox(NICE::Vector & GPMeanApproxRightPart, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  127. {
  128. Timer tTrainPrecise;
  129. tTrainPrecise.start();
  130. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  131. {
  132. NICE::Vector matrixDInv(nrOfExamplesPerClass,0.0);
  133. //compute D
  134. //start with adding some noise, if necessary
  135. if (noise != 0.0)
  136. matrixDInv.set(noise);
  137. else
  138. matrixDInv.set(0.0);
  139. // the approximation creates a diagonal matrix (which is easy to invert)
  140. // with entries equal the row sums of the original kernel matrix
  141. for (int i = 0; i < nrOfExamplesPerClass; i++)
  142. {
  143. for (int j = i; j < nrOfExamplesPerClass; j++)
  144. {
  145. matrixDInv[i] += kernelMatrix(i,j);
  146. if (i != j)
  147. matrixDInv[j] += kernelMatrix(i,j);
  148. }
  149. }
  150. //compute its inverse (and multiply every element with the label vector, which contains only one-entries and therefore be skipped...)
  151. GPMeanApproxRightPart.resize(nrOfExamplesPerClass);
  152. for (int i = 0; i < nrOfExamplesPerClass; i++)
  153. {
  154. GPMeanApproxRightPart[i] = 1.0 / matrixDInv[i];
  155. }
  156. }
  157. tTrainPrecise.stop();
  158. std::cerr << "Precise time used for GPMeanApprox training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  159. }
  160. void inline trainGPVarApprox(NICE::Vector & matrixDInv, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  161. {
  162. std::cerr << "nrOfExamplesPerClass : " << nrOfExamplesPerClass << std::endl;
  163. Timer tTrainPreciseTimer;
  164. tTrainPreciseTimer.start();
  165. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  166. {
  167. matrixDInv.resize(nrOfExamplesPerClass);
  168. matrixDInv.set(0.0);
  169. //compute D
  170. //start with adding some noise, if necessary
  171. if (noise != 0.0)
  172. matrixDInv.set(noise);
  173. else
  174. matrixDInv.set(0.0);
  175. // the approximation creates a diagonal matrix (which is easy to invert)
  176. // with entries equal the row sums of the original kernel matrix
  177. for (int i = 0; i < nrOfExamplesPerClass; i++)
  178. {
  179. for (int j = i; j < nrOfExamplesPerClass; j++)
  180. {
  181. matrixDInv[i] += kernelMatrix(i,j);
  182. if (i != j)
  183. matrixDInv[j] += kernelMatrix(i,j);
  184. }
  185. }
  186. //compute its inverse
  187. for (int i = 0; i < nrOfExamplesPerClass; i++)
  188. {
  189. matrixDInv[i] = 1.0 / matrixDInv[i];
  190. }
  191. }
  192. tTrainPreciseTimer.stop();
  193. std::cerr << "Precise time used for GPVarApprox training class " << classNumber << ": " << tTrainPreciseTimer.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. rightPartGPOptMean.resize(nrOfExamplesPerClass);
  323. Timer tTrainPrecise;
  324. tTrainPrecise.start();
  325. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  326. {
  327. rightPartGPOptMean.set(0.0);
  328. //compute optimal diagonal matrix
  329. diagApprox.approx ( kernelMatrix, rightPartGPOptMean );
  330. // invert entries
  331. // by theory we should multiply these entries with the labels
  332. // but we are in an OCC setting with labels equal to one
  333. for (int i = 0; i < nrOfExamplesPerClass; i++)
  334. {
  335. if (rightPartGPOptMean[i] != 0.0)
  336. rightPartGPOptMean[i] = 1.0 / rightPartGPOptMean[i];
  337. }
  338. }
  339. tTrainPrecise.stop();
  340. std::cerr << "Precise time used for GPOptMean training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  341. }
  342. void inline trainGPOptVar(NICE::Vector & DiagGPOptVar, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  343. {
  344. DiagonalMatrixApprox diagApprox ( true /*verbose*/ );
  345. DiagGPOptVar.resize(nrOfExamplesPerClass);
  346. Timer tTrainPrecise;
  347. tTrainPrecise.start();
  348. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  349. {
  350. DiagGPOptVar.set(0.0);
  351. //compute optimal diagonal matrix
  352. diagApprox.approx ( kernelMatrix, DiagGPOptVar );
  353. //invert entries
  354. for (int i = 0; i < nrOfExamplesPerClass; i++)
  355. {
  356. if (DiagGPOptVar[i] != 0.0)
  357. DiagGPOptVar[i] = 1.0 / DiagGPOptVar[i];
  358. }
  359. }
  360. tTrainPrecise.stop();
  361. std::cerr << "Precise time used for GPOptVar training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  362. }
  363. KCMinimumEnclosingBall *trainSVDD( const double & noise, const NICE::Matrix kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  364. {
  365. Config conf;
  366. // set the outlier ratio (Paul optimized this paramter FIXME)
  367. conf.sD( "SVDD", "outlier_fraction", 0.1 );
  368. conf.sB( "SVDD", "verbose", false );
  369. KCMinimumEnclosingBall *svdd = new KCMinimumEnclosingBall ( &conf, NULL /* no kernel function */, "SVDD" /* config section */);
  370. KernelData kernelData ( &conf, kernelMatrix, "Kernel" , false /* update cholesky */ );
  371. Timer tTrainPrecise;
  372. tTrainPrecise.start();
  373. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  374. {
  375. NICE::Vector y(nrOfExamplesPerClass,1.0); //OCC setting :)
  376. // KCMinimumEnclosingBall does not store the kernel data object, therefore, we are save with passing a local copy
  377. svdd->teach ( &kernelData, y );
  378. }
  379. tTrainPrecise.stop();
  380. std::cerr << "Precise time used for SVDD training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  381. return svdd;
  382. }
  383. // ------------- EVALUATION METHODS ---------------------
  384. void inline evaluateGPVarApprox(const NICE::Vector & kernelVector, const double & kernelSelf, const NICE::Vector & matrixDInv, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  385. {
  386. double uncertainty;
  387. Timer tTestSingle;
  388. tTestSingle.start();
  389. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  390. {
  391. // uncertainty = k{**} - \k_*^T \cdot D^{-1} \cdot k_* where D is our nice approximation of K
  392. NICE::Vector rightPart (kernelVector.size());
  393. for (int j = 0; j < kernelVector.size(); j++)
  394. {
  395. rightPart[j] = kernelVector[j] * matrixDInv[j];
  396. }
  397. uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  398. }
  399. tTestSingle.stop();
  400. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  401. FullVector scores ( 2 );
  402. scores[0] = 0.0;
  403. scores[1] = 1.0 - uncertainty;
  404. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  405. }
  406. void inline evaluateGPVar(const NICE::Vector & kernelVector, const double & kernelSelf, const NICE::Matrix & choleskyMatrix, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  407. {
  408. double uncertainty;
  409. Timer tTestSingle;
  410. tTestSingle.start();
  411. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  412. {
  413. // uncertainty = k{**} - \k_*^T \cdot D^{-1} \cdot k_*
  414. NICE::Vector rightPart (kernelVector.size(),0.0);
  415. choleskySolveLargeScale ( choleskyMatrix, kernelVector, rightPart );
  416. uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  417. }
  418. tTestSingle.stop();
  419. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  420. FullVector scores ( 2 );
  421. scores[0] = 0.0;
  422. scores[1] = 1.0 - uncertainty;
  423. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  424. }
  425. void inline evaluateGPMeanApprox(const NICE::Vector & kernelVector, const NICE::Vector & rightPart, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  426. {
  427. double mean;
  428. Timer tTestSingle;
  429. tTestSingle.start();
  430. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  431. {
  432. // \mean = \k_*^T \cdot D^{-1} \cdot y where D is our nice approximation of K
  433. mean = kernelVector.scalarProduct ( rightPart );
  434. }
  435. tTestSingle.stop();
  436. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  437. FullVector scores ( 2 );
  438. scores[0] = 0.0;
  439. scores[1] = mean;
  440. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  441. }
  442. void inline evaluateGPMean(const NICE::Vector & kernelVector, const NICE::Vector & GPMeanRightPart, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  443. {
  444. double mean;
  445. Timer tTestSingle;
  446. tTestSingle.start();
  447. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  448. {
  449. // \mean = \k_*^T \cdot K^{-1} \cdot y
  450. mean = kernelVector.scalarProduct ( GPMeanRightPart );
  451. }
  452. tTestSingle.stop();
  453. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  454. FullVector scores ( 2 );
  455. scores[0] = 0.0;
  456. scores[1] = mean;
  457. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  458. }
  459. 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)
  460. {
  461. double mean;
  462. //grep the entries corresponding to the active set
  463. NICE::Vector kernelVectorM;
  464. kernelVectorM.resize(nrOfRegressors);
  465. for (int i = 0; i < nrOfRegressors; i++)
  466. {
  467. kernelVectorM[i] = kernelVector[indicesOfChosenExamples[i]];
  468. }
  469. Timer tTestSingle;
  470. tTestSingle.start();
  471. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  472. {
  473. // \mean = \k_*^T \cdot K^{-1} \cdot y
  474. mean = kernelVectorM.scalarProduct ( GPSRMeanRightPart );
  475. }
  476. tTestSingle.stop();
  477. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  478. FullVector scores ( 2 );
  479. scores[0] = 0.0;
  480. scores[1] = mean;
  481. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  482. }
  483. 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)
  484. {
  485. double uncertainty;
  486. //grep the entries corresponding to the active set
  487. NICE::Vector kernelVectorM;
  488. kernelVectorM.resize(nrOfRegressors);
  489. for (int i = 0; i < nrOfRegressors; i++)
  490. {
  491. kernelVectorM[i] = kernelVector[indicesOfChosenExamples[i]];
  492. }
  493. Timer tTestSingle;
  494. tTestSingle.start();
  495. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  496. {
  497. NICE::Vector rightPart (nrOfRegressors,0.0);
  498. choleskySolveLargeScale ( choleskyMatrix, kernelVectorM, rightPart );
  499. uncertainty = noise*kernelVectorM.scalarProduct ( rightPart );
  500. }
  501. tTestSingle.stop();
  502. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  503. FullVector scores ( 2 );
  504. scores[0] = 0.0;
  505. scores[1] = 1.0 - uncertainty;
  506. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  507. }
  508. //this method is completely the same as evaluateGPMeanApprox, but for convenience, it is its own method
  509. void inline evaluateGPOptMean(const NICE::Vector & kernelVector, const NICE::Vector & rightPart, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  510. {
  511. double mean;
  512. Timer tTestSingle;
  513. tTestSingle.start();
  514. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  515. {
  516. // \mean = \k_*^T \cdot D^{-1} \cdot y where D is our nice approximation of K
  517. mean = kernelVector.scalarProduct ( rightPart );
  518. }
  519. tTestSingle.stop();
  520. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  521. FullVector scores ( 2 );
  522. scores[0] = 0.0;
  523. scores[1] = mean;
  524. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  525. }
  526. //this method is completely the same as evaluateGPVarApprox, but for convenience, it is its own method
  527. void inline evaluateGPOptVar(const NICE::Vector & kernelVector, const double & kernelSelf, const NICE::Vector & matrixDInv, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  528. {
  529. double uncertainty;
  530. Timer tTestSingle;
  531. tTestSingle.start();
  532. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  533. {
  534. // uncertainty = k{**} - \k_*^T \cdot D^{-1} \cdot k_* where D is our nice approximation of K
  535. NICE::Vector rightPart (kernelVector.size());
  536. for (int j = 0; j < kernelVector.size(); j++)
  537. {
  538. rightPart[j] = kernelVector[j] * matrixDInv[j];
  539. }
  540. uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  541. }
  542. tTestSingle.stop();
  543. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  544. FullVector scores ( 2 );
  545. scores[0] = 0.0;
  546. scores[1] = 1.0 - uncertainty;
  547. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  548. }
  549. void inline evaluateParzen(const NICE::Vector & kernelVector, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  550. {
  551. double score;
  552. Timer tTestSingle;
  553. tTestSingle.start();
  554. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  555. {
  556. //the Parzen score is nothing but the averaged similarity to every training sample
  557. score = kernelVector.Sum() / (double) kernelVector.size(); //maybe we could directly call kernelVector.Mean() here
  558. }
  559. tTestSingle.stop();
  560. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  561. FullVector scores ( 2 );
  562. scores[0] = 0.0;
  563. scores[1] = score;
  564. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  565. }
  566. void inline evaluateSVDD( KCMinimumEnclosingBall *svdd, const NICE::Vector & kernelVector, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  567. {
  568. Timer tTestSingle;
  569. tTestSingle.start();
  570. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  571. {
  572. // In the following, we assume that we are using a Gaussian kernel
  573. r = svdd->classifyKernel ( kernelVector, 1.0 /* kernel self */ );
  574. }
  575. tTestSingle.stop();
  576. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  577. }
  578. /**
  579. test the basic functionality of fast-hik hyperparameter optimization
  580. */
  581. int main (int argc, char **argv)
  582. {
  583. std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
  584. Config conf ( argc, argv );
  585. string resultsfile = conf.gS("main", "results", "results.txt" );
  586. int nrOfExamplesPerClass = conf.gI("main", "nrOfExamplesPerClass", 50);
  587. nrOfExamplesPerClass = std::min(nrOfExamplesPerClass, 100); // we do not have more than 100 examples per class
  588. //which classes to considere? we assume consecutive class numers
  589. int indexOfFirstClass = conf.gI("main", "indexOfFirstClass", 0);
  590. indexOfFirstClass = std::max(indexOfFirstClass, 0); //we do not have less than 0 classes
  591. int indexOfLastClass = conf.gI("main", "indexOfLastClass", 999);
  592. indexOfLastClass = std::min(indexOfLastClass, 999); //we do not have more than 1000 classes
  593. int nrOfClassesToConcidere = (indexOfLastClass - indexOfLastClass)+1;
  594. //repetitions for every class to achieve reliable time evalutions
  595. int runsPerClassToAverageTraining = conf.gI( "main", "runsPerClassToAverageTraining", 1 );
  596. int runsPerClassToAverageTesting = conf.gI( "main", "runsPerClassToAverageTesting", 1 );
  597. // share parameters among methods and classes?
  598. bool shareParameters = conf.gB("main" , "shareParameters", true);
  599. //which methods do we want to use?
  600. bool GPMeanApprox = conf.gB( "main", "GPMeanApprox", false);
  601. bool GPVarApprox = conf.gB( "main", "GPVarApprox", false);
  602. bool GPMean = conf.gB( "main", "GPMean", false);
  603. bool GPVar = conf.gB( "main", "GPVar", false);
  604. bool GPSRMean = conf.gB( "main", "GPSRMean", false);
  605. bool GPSRVar = conf.gB( "main", "GPSRVar", false);
  606. bool GPOptMean = conf.gB( "main", "GPOptMean", false);
  607. bool GPOptVar = conf.gB( "main", "GPOptVar", false);
  608. bool Parzen = conf.gB( "main", "Parzen", false);
  609. bool SVDD = conf.gB( "main", "SVDD", false);
  610. if (GPMeanApprox)
  611. std::cerr << "GPMeanApprox used" << std::endl;
  612. else
  613. std::cerr << "GPMeanApprox not used" << std::endl;
  614. if (GPVarApprox)
  615. std::cerr << "GPVarApprox used" << std::endl;
  616. else
  617. std::cerr << "GPVarApprox not used" << std::endl;
  618. if (GPMean)
  619. std::cerr << "GPMean used" << std::endl;
  620. else
  621. std::cerr << "GPMean not used" << std::endl;
  622. if (GPVar)
  623. std::cerr << "GPVar used" << std::endl;
  624. else
  625. std::cerr << "GPVar not used" << std::endl;
  626. if (GPSRMean)
  627. std::cerr << "GPSRMean used" << std::endl;
  628. else
  629. std::cerr << "GPSRMean not used" << std::endl;
  630. if (GPSRVar)
  631. std::cerr << "GPSRVar used" << std::endl;
  632. else
  633. std::cerr << "GPSRVar not used" << std::endl;
  634. if (GPOptMean)
  635. std::cerr << "GPOptMean used" << std::endl;
  636. else
  637. std::cerr << "GPOptMean not used" << std::endl;
  638. if (GPOptVar)
  639. std::cerr << "GPOptVar used" << std::endl;
  640. else
  641. std::cerr << "GPOptVar not used" << std::endl;
  642. if (Parzen)
  643. std::cerr << "Parzen used" << std::endl;
  644. else
  645. std::cerr << "Parzen not used" << std::endl;
  646. if (SVDD)
  647. std::cerr << "SVDD used" << std::endl;
  648. else
  649. std::cerr << "SVDD not used" << std::endl;
  650. // GP variance approximation
  651. NICE::Vector sigmaGPVarApproxParas(nrOfClassesToConcidere,0.0);
  652. NICE::Vector noiseGPVarApproxParas(nrOfClassesToConcidere,0.0);
  653. // GP variance
  654. NICE::Vector sigmaGPVarParas(nrOfClassesToConcidere,0.0);
  655. NICE::Vector noiseGPVarParas(nrOfClassesToConcidere,0.0);
  656. //GP mean approximation
  657. NICE::Vector sigmaGPMeanApproxParas(nrOfClassesToConcidere,0.0);
  658. NICE::Vector noiseGPMeanApproxParas(nrOfClassesToConcidere,0.0);
  659. //GP mean
  660. NICE::Vector sigmaGPMeanParas(nrOfClassesToConcidere,0.0);
  661. NICE::Vector noiseGPMeanParas(nrOfClassesToConcidere,0.0);
  662. //GP SR mean
  663. NICE::Vector sigmaGPSRMeanParas(nrOfClassesToConcidere,0.0);
  664. NICE::Vector noiseGPSRMeanParas(nrOfClassesToConcidere,0.0);
  665. //GP SR var
  666. NICE::Vector sigmaGPSRVarParas(nrOfClassesToConcidere,0.0);
  667. NICE::Vector noiseGPSRVarParas(nrOfClassesToConcidere,0.0);
  668. //GP Opt mean
  669. NICE::Vector sigmaGPOptMeanParas(nrOfClassesToConcidere,0.0);
  670. NICE::Vector noiseGPOptMeanParas(nrOfClassesToConcidere,0.0);
  671. //GP Opt var
  672. NICE::Vector sigmaGPOptVarParas(nrOfClassesToConcidere,0.0);
  673. NICE::Vector noiseGPOptVarParas(nrOfClassesToConcidere,0.0);
  674. //Parzen
  675. NICE::Vector sigmaParzenParas(nrOfClassesToConcidere,0.0);
  676. NICE::Vector noiseParzenParas(nrOfClassesToConcidere,0.0);
  677. //SVDD
  678. NICE::Vector sigmaSVDDParas(nrOfClassesToConcidere,0.0);
  679. NICE::Vector noiseSVDDParas(nrOfClassesToConcidere,0.0);
  680. if (!shareParameters)
  681. {
  682. //read the optimal parameters for the different methods
  683. // GP variance approximation
  684. string sigmaGPVarApproxFile = conf.gS("main", "sigmaGPVarApproxFile", "approxVarSigma.txt");
  685. string noiseGPVarApproxFile = conf.gS("main", "noiseGPVarApproxFile", "approxVarNoise.txt");
  686. // GP variance
  687. string sigmaGPVarFile = conf.gS("main", "sigmaGPVarFile", "approxVarSigma.txt");
  688. string noiseGPVarFile = conf.gS("main", "noiseGPVarFile", "approxVarNoise.txt");
  689. //GP mean approximation
  690. string sigmaGPMeanApproxFile = conf.gS("main", "sigmaGPMeanApproxFile", "approxVarSigma.txt");
  691. string noiseGPMeanApproxFile = conf.gS("main", "noiseGPMeanApproxFile", "approxVarNoise.txt");
  692. //GP mean
  693. string sigmaGPMeanFile = conf.gS("main", "sigmaGPMeanFile", "approxVarSigma.txt");
  694. string noiseGPMeanFile = conf.gS("main", "noiseGPMeanFile", "approxVarNoise.txt");
  695. //Parzen
  696. string sigmaParzenFile = conf.gS("main", "sigmaParzenFile", "approxVarSigma.txt");
  697. string noiseParzenFile = conf.gS("main", "noiseParzenFile", "approxVarNoise.txt");
  698. //SVDD
  699. string sigmaSVDDFile = conf.gS("main", "sigmaSVDDFile", "approxVarSigma.txt");
  700. string noiseSVDDFile = conf.gS("main", "noiseSVDDFile", "approxVarNoise.txt");
  701. // GP variance approximation
  702. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPVarApproxParas);
  703. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPVarApproxParas);
  704. // GP variance
  705. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPVarParas);
  706. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPVarParas);
  707. //GP mean approximation
  708. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPMeanApproxParas);
  709. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPMeanApproxParas);
  710. //GP mean
  711. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPMeanParas);
  712. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPMeanParas);
  713. //GP SR mean
  714. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPSRMeanParas);
  715. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPSRMeanParas);
  716. //GP SR var
  717. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPSRVarParas);
  718. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPSRVarParas);
  719. //GP Opt mean
  720. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPOptMeanParas);
  721. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPOptMeanParas);
  722. //GP Opt var
  723. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPOptVarParas);
  724. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPOptVarParas);
  725. //Parzen
  726. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaParzenParas);
  727. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseParzenParas);
  728. //SVDD
  729. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaSVDDParas);
  730. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseSVDDParas);
  731. }
  732. else
  733. {
  734. //use static variables for all methods and classis
  735. double noise = conf.gD( "main", "noise", 0.01 );
  736. double sigma = conf.gD( "main", "sigma", 1.0 );
  737. sigmaGPVarApproxParas.set(sigma);
  738. noiseGPVarApproxParas.set(noise);
  739. // GP variance
  740. sigmaGPVarParas.set(sigma);
  741. noiseGPVarParas.set(noise);
  742. //GP mean approximation
  743. sigmaGPMeanApproxParas.set(sigma);
  744. noiseGPMeanApproxParas.set(noise);
  745. //GP mean
  746. sigmaGPMeanParas.set(sigma);
  747. noiseGPMeanParas.set(noise);
  748. //GP SR mean
  749. sigmaGPSRMeanParas.set(sigma);
  750. noiseGPSRMeanParas.set(noise);
  751. //GP SR var
  752. sigmaGPSRVarParas.set(sigma);
  753. noiseGPSRVarParas.set(noise);
  754. //GP Opt mean
  755. sigmaGPOptMeanParas.set(sigma);
  756. noiseGPOptMeanParas.set(noise);
  757. //GP Opt var
  758. sigmaGPOptVarParas.set(sigma);
  759. noiseGPOptVarParas.set(noise);
  760. //Parzen
  761. sigmaParzenParas.set(sigma);
  762. noiseParzenParas.set(noise);
  763. //SVDD
  764. sigmaSVDDParas.set(sigma);
  765. noiseSVDDParas.set(noise);
  766. }
  767. // -------- optimal parameters read --------------
  768. std::vector<SparseVector> trainingData;
  769. NICE::Vector y;
  770. std::cerr << "Reading ImageNet data ..." << std::endl;
  771. bool imageNetLocal = conf.gB("main", "imageNetLocal" , false);
  772. string imageNetPath;
  773. if (imageNetLocal)
  774. imageNetPath = "/users2/rodner/data/imagenet/devkit-1.0/";
  775. else
  776. imageNetPath = "/home/dbv/bilder/imagenet/devkit-1.0/";
  777. ImageNetData imageNetTrain ( imageNetPath + "demo/" );
  778. imageNetTrain.preloadData( "train", "training" );
  779. trainingData = imageNetTrain.getPreloadedData();
  780. y = imageNetTrain.getPreloadedLabels();
  781. std::cerr << "Reading of training data finished" << std::endl;
  782. std::cerr << "trainingData.size(): " << trainingData.size() << std::endl;
  783. std::cerr << "y.size(): " << y.size() << std::endl;
  784. std::cerr << "Reading ImageNet test data files (takes some seconds)..." << std::endl;
  785. ImageNetData imageNetTest ( imageNetPath + "demo/" );
  786. imageNetTest.preloadData ( "val", "testing" );
  787. imageNetTest.loadExternalLabels ( imageNetPath + "data/ILSVRC2010_validation_ground_truth.txt" );
  788. double OverallPerformanceGPVarApprox(0.0);
  789. double OverallPerformanceGPVar(0.0);
  790. double OverallPerformanceGPMeanApprox(0.0);
  791. double OverallPerformanceGPMean(0.0);
  792. double OverallPerformanceGPSRMean(0.0);
  793. double OverallPerformanceGPSRVar(0.0);
  794. double OverallPerformanceGPOptMean(0.0);
  795. double OverallPerformanceGPOptVar(0.0);
  796. double OverallPerformanceParzen(0.0);
  797. double OverallPerformanceSVDD(0.0);
  798. double kernelSigmaGPVarApprox;
  799. double kernelSigmaGPVar;
  800. double kernelSigmaGPMeanApprox;
  801. double kernelSigmaGPMean;
  802. double kernelSigmaGPSRMean;
  803. double kernelSigmaGPSRVar;
  804. double kernelSigmaGPOptMean;
  805. double kernelSigmaGPOptVar;
  806. double kernelSigmaParzen;
  807. double kernelSigmaSVDD;
  808. for (int cl = indexOfFirstClass; cl <= indexOfLastClass; cl++)
  809. {
  810. std::cerr << "run for class " << cl << std::endl;
  811. int positiveClass = cl+1; //labels are from 1 to 1000, but our indices from 0 to 999
  812. // ------------------------------ TRAINING ------------------------------
  813. kernelSigmaGPVarApprox = sigmaGPVarApproxParas[cl];
  814. kernelSigmaGPVar = sigmaGPVarParas[cl];
  815. kernelSigmaGPMeanApprox = sigmaGPMeanApproxParas[cl];
  816. kernelSigmaGPMean = sigmaGPMeanParas[cl];
  817. kernelSigmaGPSRMean = sigmaGPSRMeanParas[cl];
  818. kernelSigmaGPSRVar = sigmaGPSRVarParas[cl];
  819. kernelSigmaGPOptMean = sigmaGPOptMeanParas[cl];
  820. kernelSigmaGPOptVar = sigmaGPOptVarParas[cl];
  821. kernelSigmaParzen = sigmaParzenParas[cl];
  822. kernelSigmaSVDD = sigmaSVDDParas[cl];
  823. Timer tTrain;
  824. tTrain.start();
  825. //compute the kernel matrix, which will be shared among all methods in this scenario
  826. NICE::Matrix kernelMatrix(nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0);
  827. //NOTE in theory we have to compute a single kernel Matrix for every method, since every method may have its own optimal parameter
  828. // I'm sure, we can speed it up a bit and compute it only for every different parameter
  829. //nonetheless, it's not as nice as we originally thought (same matrix for every method)
  830. //NOTE Nonetheless, since we're only interested in runtimes, we can ignore this
  831. //now sum up all entries of each row in the original kernel matrix
  832. double kernelScore(0.0);
  833. for (int i = cl*100; i < cl*100+nrOfExamplesPerClass; i++)
  834. {
  835. for (int j = i; j < cl*100+nrOfExamplesPerClass; j++)
  836. {
  837. kernelScore = measureDistance(trainingData[i],trainingData[j], kernelSigmaGPVarApprox);
  838. kernelMatrix(i-cl*100,j-cl*100) = kernelScore;
  839. if (i != j)
  840. kernelMatrix(j-cl*100,i-cl*100) = kernelScore;
  841. }
  842. }
  843. // now call the individual training methods
  844. //train GP Mean Approx
  845. NICE::Vector GPMeanApproxRightPart;
  846. if (GPMeanApprox)
  847. trainGPMeanApprox(GPMeanApproxRightPart, noiseGPMeanApproxParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  848. //train GP Var Approx
  849. NICE::Vector matrixDInv;
  850. if (GPVarApprox)
  851. trainGPVarApprox(matrixDInv, noiseGPVarApproxParas[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 Var
  857. NICE::Matrix GPVarCholesky;
  858. if (GPVar)
  859. trainGPVar(GPVarCholesky, noiseGPVarParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  860. //train GP SR Mean
  861. NICE::Vector GPSRMeanRightPart;
  862. std::vector<int> indicesOfChosenExamplesGPSRMean;
  863. int nrOfRegressors = conf.gI( "GPSR", "nrOfRegressors", nrOfExamplesPerClass/2);
  864. nrOfRegressors = std::min( nrOfRegressors, nrOfExamplesPerClass );
  865. if (GPSRMean)
  866. trainGPSRMean(GPSRMeanRightPart, noiseGPSRMeanParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining, nrOfRegressors, indicesOfChosenExamplesGPSRMean );
  867. //train GP SR Var
  868. NICE::Matrix GPSRVarCholesky;
  869. std::vector<int> indicesOfChosenExamplesGPSRVar;
  870. if (GPSRVar)
  871. trainGPSRVar(GPSRVarCholesky, noiseGPSRVarParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining, nrOfRegressors, indicesOfChosenExamplesGPSRVar );
  872. //train GP Opt Mean
  873. NICE::Vector GPOptMeanRightPart;
  874. if (GPOptMean)
  875. trainGPOptMean(GPOptMeanRightPart, noiseGPOptMeanParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  876. //train GP Opt Var
  877. NICE::Vector DiagGPOptVar;
  878. if (GPOptVar)
  879. trainGPOptVar(DiagGPOptVar, noiseGPOptVarParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  880. //train Parzen
  881. //nothing to do :)
  882. //train SVDD
  883. KCMinimumEnclosingBall *svdd;
  884. if (SVDD)
  885. svdd = trainSVDD(noiseSVDDParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  886. tTrain.stop();
  887. std::cerr << "Time used for training class " << cl << ": " << tTrain.getLast() << std::endl;
  888. std::cerr << "training done - now perform the evaluation" << std::endl;
  889. // ------------------------------ TESTING ------------------------------
  890. std::cerr << "Classification step ... with " << imageNetTest.getNumPreloadedExamples() << " examples" << std::endl;
  891. ClassificationResults resultsGPVarApprox;
  892. ClassificationResults resultsGPVar;
  893. ClassificationResults resultsGPMeanApprox;
  894. ClassificationResults resultsGPMean;
  895. ClassificationResults resultsGPSRMean;
  896. ClassificationResults resultsGPSRVar;
  897. ClassificationResults resultsGPOptMean;
  898. ClassificationResults resultsGPOptVar;
  899. ClassificationResults resultsParzen;
  900. ClassificationResults resultsSVDD;
  901. ProgressBar pb;
  902. Timer tTest;
  903. tTest.start();
  904. Timer tTestSingle;
  905. double timeForSingleExamplesGPVarApprox(0.0);
  906. double timeForSingleExamplesGPVar(0.0);
  907. double timeForSingleExamplesGPMeanApprox(0.0);
  908. double timeForSingleExamplesGPMean(0.0);
  909. double timeForSingleExamplesGPSRMean(0.0);
  910. double timeForSingleExamplesGPSRVar(0.0);
  911. double timeForSingleExamplesGPOptMean(0.0);
  912. double timeForSingleExamplesGPOptVar(0.0);
  913. double timeForSingleExamplesParzen(0.0);
  914. double timeForSingleExamplesSVDD(0.0);
  915. for ( uint i = 0 ; i < (uint)imageNetTest.getNumPreloadedExamples(); i++ )
  916. {
  917. pb.update ( imageNetTest.getNumPreloadedExamples() );
  918. const SparseVector & svec = imageNetTest.getPreloadedExample ( i );
  919. //NOTE: again we should use method-specific optimal parameters. If we're only interested in the runtimes, this doesn't matter
  920. //compute (self) similarities
  921. double kernelSelf (measureDistance(svec,svec, kernelSigmaGPVarApprox) );
  922. NICE::Vector kernelVector (nrOfExamplesPerClass, 0.0);
  923. for (int j = 0; j < nrOfExamplesPerClass; j++)
  924. {
  925. kernelVector[j] = measureDistance(trainingData[j+cl*100],svec, kernelSigmaGPVarApprox);
  926. }
  927. //call the individual test-methods
  928. //evaluate GP Var Approx
  929. ClassificationResult rGPVarApprox;
  930. if (GPVarApprox)
  931. evaluateGPVarApprox( kernelVector, kernelSelf, matrixDInv, rGPVarApprox, timeForSingleExamplesGPVarApprox, runsPerClassToAverageTesting );
  932. //evaluate GP Var
  933. ClassificationResult rGPVar;
  934. if (GPVar)
  935. evaluateGPVar( kernelVector, kernelSelf, GPVarCholesky, rGPVar, timeForSingleExamplesGPVar, runsPerClassToAverageTesting );
  936. //evaluate GP Mean Approx
  937. ClassificationResult rGPMeanApprox;
  938. if (GPMeanApprox)
  939. evaluateGPMeanApprox( kernelVector, matrixDInv, rGPMeanApprox, timeForSingleExamplesGPMeanApprox, runsPerClassToAverageTesting );
  940. //evaluate GP Mean
  941. ClassificationResult rGPMean;
  942. if (GPMean)
  943. evaluateGPMean( kernelVector, GPMeanRightPart, rGPMean, timeForSingleExamplesGPMean, runsPerClassToAverageTesting );
  944. //evaluate GP SR Mean
  945. ClassificationResult rGPSRMean;
  946. if (GPSRMean)
  947. evaluateGPSRMean( kernelVector, GPSRMeanRightPart, rGPSRMean, timeForSingleExamplesGPSRMean, runsPerClassToAverageTesting, nrOfRegressors, indicesOfChosenExamplesGPSRMean );
  948. //evaluate GP SR Var
  949. ClassificationResult rGPSRVar;
  950. if (GPSRVar)
  951. evaluateGPSRVar( kernelVector, GPSRVarCholesky, rGPSRVar, timeForSingleExamplesGPSRVar, runsPerClassToAverageTesting, nrOfRegressors, indicesOfChosenExamplesGPSRVar, noiseGPSRVarParas[cl] );
  952. //evaluate GP Opt Mean
  953. ClassificationResult rGPOptMean;
  954. if (GPOptMean)
  955. evaluateGPOptMean( kernelVector, GPOptMeanRightPart, rGPOptMean, timeForSingleExamplesGPOptMean, runsPerClassToAverageTesting );
  956. //evaluate GP Opt Var
  957. ClassificationResult rGPOptVar;
  958. if (GPOptVar)
  959. evaluateGPOptVar( kernelVector, kernelSelf, DiagGPOptVar, rGPOptVar, timeForSingleExamplesGPOptVar, runsPerClassToAverageTesting );
  960. //evaluate Parzen
  961. ClassificationResult rParzen;
  962. if (Parzen)
  963. evaluateParzen( kernelVector, rParzen, timeForSingleExamplesParzen, runsPerClassToAverageTesting );
  964. //evaluate SVDD
  965. ClassificationResult rSVDD;
  966. if (SVDD)
  967. evaluateSVDD( svdd, kernelVector, rSVDD, timeForSingleExamplesSVDD, runsPerClassToAverageTesting );
  968. // set ground truth label
  969. rGPVarApprox.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  970. rGPVar.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  971. rGPMeanApprox.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  972. rGPMean.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  973. rGPSRMean.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  974. rGPSRVar.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  975. rGPOptMean.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  976. rGPOptVar.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  977. rParzen.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  978. rSVDD.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  979. //remember the results for the evaluation lateron
  980. resultsGPVarApprox.push_back ( rGPVarApprox );
  981. resultsGPVar.push_back ( rGPVar );
  982. resultsGPMeanApprox.push_back ( rGPMeanApprox );
  983. resultsGPMean.push_back ( rGPMean );
  984. resultsGPSRMean.push_back ( rGPSRMean );
  985. resultsGPSRVar.push_back ( rGPSRVar );
  986. resultsGPOptMean.push_back ( rGPOptMean );
  987. resultsGPOptVar.push_back ( rGPOptVar );
  988. resultsParzen.push_back ( rParzen );
  989. resultsSVDD.push_back ( rSVDD );
  990. }
  991. tTest.stop();
  992. std::cerr << "Time used for evaluating class " << cl << ": " << tTest.getLast() << std::endl;
  993. timeForSingleExamplesGPVarApprox/= imageNetTest.getNumPreloadedExamples();
  994. timeForSingleExamplesGPVar/= imageNetTest.getNumPreloadedExamples();
  995. timeForSingleExamplesGPMeanApprox/= imageNetTest.getNumPreloadedExamples();
  996. timeForSingleExamplesGPMean/= imageNetTest.getNumPreloadedExamples();
  997. timeForSingleExamplesGPSRMean/= imageNetTest.getNumPreloadedExamples();
  998. timeForSingleExamplesGPSRVar/= imageNetTest.getNumPreloadedExamples();
  999. timeForSingleExamplesGPOptMean/= imageNetTest.getNumPreloadedExamples();
  1000. timeForSingleExamplesGPOptVar/= imageNetTest.getNumPreloadedExamples();
  1001. timeForSingleExamplesParzen/= imageNetTest.getNumPreloadedExamples();
  1002. timeForSingleExamplesSVDD/= imageNetTest.getNumPreloadedExamples();
  1003. std::cerr << "GPVarApprox -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPVarApprox << std::endl;
  1004. std::cerr << "GPVar -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPVar << std::endl;
  1005. std::cerr << "GPMeanApprox -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPMeanApprox << std::endl;
  1006. std::cerr << "GPMean -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPMean << std::endl;
  1007. std::cerr << "GPSRMean -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPSRMean << std::endl;
  1008. std::cerr << "GPSRVar -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPSRVar << std::endl;
  1009. std::cerr << "GPOptMean -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPOptMean << std::endl;
  1010. std::cerr << "GPOptVar -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPOptVar << std::endl;
  1011. std::cerr << "Parzen -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesParzen << std::endl;
  1012. std::cerr << "SVDD -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesSVDD << std::endl;
  1013. // run the AUC-evaluation
  1014. double perfvalueGPVarApprox( 0.0 );
  1015. double perfvalueGPVar( 0.0 );
  1016. double perfvalueGPMeanApprox( 0.0 );
  1017. double perfvalueGPMean( 0.0 );
  1018. double perfvalueGPSRMean( 0.0 );
  1019. double perfvalueGPSRVar( 0.0 );
  1020. double perfvalueGPOptMean( 0.0 );
  1021. double perfvalueGPOptVar( 0.0 );
  1022. double perfvalueParzen( 0.0 );
  1023. double perfvalueSVDD( 0.0 );
  1024. if (GPVarApprox)
  1025. perfvalueGPVarApprox = resultsGPVarApprox.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1026. if (GPVar)
  1027. perfvalueGPVar = resultsGPVar.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1028. if (GPMeanApprox)
  1029. perfvalueGPMeanApprox = resultsGPMeanApprox.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1030. if (GPMean)
  1031. perfvalueGPMean = resultsGPMean.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1032. if (GPSRMean)
  1033. perfvalueGPSRMean = resultsGPSRMean.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1034. if (GPSRVar)
  1035. perfvalueGPSRVar = resultsGPSRVar.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1036. if (GPOptMean)
  1037. perfvalueGPOptMean = resultsGPOptMean.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1038. if (GPOptVar)
  1039. perfvalueGPOptVar = resultsGPOptVar.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1040. if (Parzen)
  1041. perfvalueParzen = resultsParzen.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1042. if (SVDD)
  1043. perfvalueSVDD = resultsSVDD.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1044. std::cerr << "Performance GPVarApprox: " << perfvalueGPVarApprox << std::endl;
  1045. std::cerr << "Performance GPVar: " << perfvalueGPVar << std::endl;
  1046. std::cerr << "Performance GPMeanApprox: " << perfvalueGPMeanApprox << std::endl;
  1047. std::cerr << "Performance GPMean: " << perfvalueGPMean << std::endl;
  1048. std::cerr << "Performance GPSRMean: " << perfvalueGPSRMean << std::endl;
  1049. std::cerr << "Performance GPSRVar: " << perfvalueGPSRVar << std::endl;
  1050. std::cerr << "Performance GPOptMean: " << perfvalueGPOptMean << std::endl;
  1051. std::cerr << "Performance GPOptVar: " << perfvalueGPOptVar << std::endl;
  1052. std::cerr << "Performance Parzen: " << perfvalueParzen << std::endl;
  1053. std::cerr << "Performance SVDD: " << perfvalueSVDD << std::endl;
  1054. OverallPerformanceGPVarApprox += perfvalueGPVar;
  1055. OverallPerformanceGPVar += perfvalueGPVarApprox;
  1056. OverallPerformanceGPMeanApprox += perfvalueGPMeanApprox;
  1057. OverallPerformanceGPMean += perfvalueGPMean;
  1058. OverallPerformanceGPSRMean += perfvalueGPSRMean;
  1059. OverallPerformanceGPSRVar += perfvalueGPSRVar;
  1060. OverallPerformanceGPOptMean += perfvalueGPOptMean;
  1061. OverallPerformanceGPOptVar += perfvalueGPOptVar;
  1062. OverallPerformanceParzen += perfvalueParzen;
  1063. OverallPerformanceSVDD += perfvalueSVDD;
  1064. // clean up memory used by SVDD
  1065. if (SVDD)
  1066. delete svdd;
  1067. }
  1068. OverallPerformanceGPVarApprox /= nrOfClassesToConcidere;
  1069. OverallPerformanceGPVar /= nrOfClassesToConcidere;
  1070. OverallPerformanceGPMeanApprox /= nrOfClassesToConcidere;
  1071. OverallPerformanceGPMean /= nrOfClassesToConcidere;
  1072. OverallPerformanceGPSRMean /= nrOfClassesToConcidere;
  1073. OverallPerformanceGPSRVar /= nrOfClassesToConcidere;
  1074. OverallPerformanceGPOptMean /= nrOfClassesToConcidere;
  1075. OverallPerformanceGPOptVar /= nrOfClassesToConcidere;
  1076. OverallPerformanceParzen /= nrOfClassesToConcidere;
  1077. OverallPerformanceSVDD /= nrOfClassesToConcidere;
  1078. std::cerr << "overall performance GPVarApprox: " << OverallPerformanceGPVarApprox << std::endl;
  1079. std::cerr << "overall performance GPVar: " << OverallPerformanceGPVar << std::endl;
  1080. std::cerr << "overall performance GPMeanApprox: " << OverallPerformanceGPMeanApprox << std::endl;
  1081. std::cerr << "overall performance GPMean: " << OverallPerformanceGPMean << std::endl;
  1082. std::cerr << "overall performance GPSRMean: " << OverallPerformanceGPSRMean << std::endl;
  1083. std::cerr << "overall performance GPSRVar: " << OverallPerformanceGPSRVar << std::endl;
  1084. std::cerr << "overall performance GPOptMean: " << OverallPerformanceGPOptMean << std::endl;
  1085. std::cerr << "overall performance GPOptVar: " << OverallPerformanceGPOptVar << std::endl;
  1086. std::cerr << "overall performance Parzen: " << OverallPerformanceParzen << std::endl;
  1087. std::cerr << "overall performance SVDD: " << OverallPerformanceSVDD << std::endl;
  1088. return 0;
  1089. }