testImageNetBinaryBruteForce.cpp 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779
  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. #ifdef NICE_USELIB_MATIO
  8. #include <ctime>
  9. #include <time.h>
  10. #include "core/basics/Config.h"
  11. #include "core/basics/Timer.h"
  12. #include "core/algebra/CholeskyRobust.h"
  13. #include "core/algebra/DiagonalMatrixApprox.h"
  14. #include "core/vector/Algorithms.h"
  15. #include "core/vector/SparseVectorT.h"
  16. #include "vislearning/cbaselib/ClassificationResults.h"
  17. #include "vislearning/baselib/ProgressBar.h"
  18. #include "vislearning/classifier/kernelclassifier/KCMinimumEnclosingBall.h"
  19. #include "core/matlabAccess/MatFileIO.h"
  20. #include "vislearning/matlabAccessHighLevel/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 (uint 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 (uint i = 0; i < indicesOfChosenExamples.size(); i++ )
  229. {
  230. for (uint 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 (uint 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 (uint i = 0; i < indicesOfChosenExamples.size(); i++ )
  294. {
  295. for (uint 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. // GP FITC approx
  320. void inline trainGPFITCMean(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 )
  321. {
  322. std::vector<int> examplesToChoose;
  323. indicesOfChosenExamples.clear();
  324. //add all examples for possible choice
  325. for (int i = 0; i < nrOfExamplesPerClass; i++)
  326. {
  327. examplesToChoose.push_back(i);
  328. }
  329. //now chose randomly some examples as active subset
  330. int index;
  331. for (int i = 0; i < std::min(nrOfRegressors,nrOfExamplesPerClass); i++)
  332. {
  333. index = rand() % examplesToChoose.size();
  334. indicesOfChosenExamples.push_back(examplesToChoose[index]);
  335. examplesToChoose.erase(examplesToChoose.begin() + index);
  336. }
  337. NICE::Vector diagK (nrOfExamplesPerClass, 0.0);
  338. //set every element
  339. for (int i = 0; i < nrOfExamplesPerClass; i++ )
  340. {
  341. diagK(i) = kernelMatrix(i,i);
  342. }
  343. NICE::Matrix Ku (indicesOfChosenExamples.size(), nrOfExamplesPerClass, 0.0);
  344. int rowCnt(0);
  345. //set every row
  346. for (uint i = 0; i < indicesOfChosenExamples.size(); i++, rowCnt++ )
  347. {
  348. //set every element of this row
  349. NICE::Vector col = kernelMatrix.getRow(indicesOfChosenExamples[i]);
  350. for (int j = 0; j < nrOfExamplesPerClass; j++)
  351. {
  352. Ku(rowCnt,j) = col(j);
  353. }
  354. }
  355. //we could speed this up if we would order the indices
  356. NICE::Matrix Kuu (indicesOfChosenExamples.size(), indicesOfChosenExamples.size(), 0.0);
  357. double tmp(0.0);
  358. for (uint i = 0; i < indicesOfChosenExamples.size(); i++ )
  359. {
  360. for (uint j = i; j < indicesOfChosenExamples.size(); j++ )
  361. {
  362. tmp = kernelMatrix(indicesOfChosenExamples[i], indicesOfChosenExamples[j]);
  363. Kuu(i,j) = tmp;
  364. if (i != j)
  365. Kuu(j,i) = tmp;
  366. }
  367. }
  368. NICE::Vector y(nrOfExamplesPerClass,1.0); //OCC setting :)
  369. Timer tTrainPrecise;
  370. tTrainPrecise.start();
  371. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  372. {
  373. // NICE::Vector projectedLabels;
  374. // projectedLabels.multiply(Kmn,y);
  375. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  376. NICE::Matrix Luu (nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0);
  377. cr.robustChol ( Kuu, Luu );
  378. NICE::Matrix V (Ku);
  379. choleskySolveMatrixLargeScale( Luu, V);
  380. NICE::Vector dg (diagK);
  381. NICE::Vector sumV (diagK.size(),0.0);
  382. for (uint i=0; i<V.cols(); i++)
  383. {
  384. for (uint j=0; j<V.rows(); j++)
  385. {
  386. sumV(i) += V(j,i)*V(j,i);
  387. }
  388. sumV(i) += noise;
  389. }
  390. dg += sumV;
  391. for (uint i=0; i<V.cols(); i++)
  392. {
  393. for (uint j=0; j<V.rows(); j++)
  394. {
  395. V(j,i) /= sqrt(dg(i));
  396. }
  397. }
  398. NICE::Matrix Lu (indicesOfChosenExamples.size(), indicesOfChosenExamples.size(), 0.0);
  399. NICE::Matrix tmpVV (indicesOfChosenExamples.size(), indicesOfChosenExamples.size(), 0.0);
  400. tmpVV.multiply(V,V,false,true);
  401. tmpVV.addIdentity(1.0);
  402. cr.robustChol ( tmpVV, Lu );
  403. NICE::Vector r (dg);
  404. for (uint i=0; i<r.size(); i++)
  405. {
  406. r(i) = 1.0/sqrt(r(i));
  407. }
  408. NICE::Vector be (indicesOfChosenExamples.size(), 0.0);
  409. choleskySolveLargeScale (Lu, V*r, be);
  410. choleskySolveLargeScale (Lu.transpose(), be, be);
  411. GPMeanRightPart.resize(indicesOfChosenExamples.size());
  412. GPMeanRightPart.set(0.0);
  413. choleskySolveLargeScale ( Luu.transpose(), be, GPMeanRightPart );
  414. }
  415. tTrainPrecise.stop();
  416. std::cerr << "Precise time used for GPFITCMean training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  417. }
  418. // GP FITC approx
  419. void inline trainGPFITCVar(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 )
  420. {
  421. std::vector<int> examplesToChoose;
  422. indicesOfChosenExamples.clear();
  423. //add all examples for possible choice
  424. for (int i = 0; i < nrOfExamplesPerClass; i++)
  425. {
  426. examplesToChoose.push_back(i);
  427. }
  428. //now chose randomly some examples as active subset
  429. int index;
  430. for (int i = 0; i < std::min(nrOfRegressors,nrOfExamplesPerClass); i++)
  431. {
  432. index = rand() % examplesToChoose.size();
  433. indicesOfChosenExamples.push_back(examplesToChoose[index]);
  434. examplesToChoose.erase(examplesToChoose.begin() + index);
  435. }
  436. NICE::Vector diagK (nrOfExamplesPerClass, 0.0);
  437. //set every element
  438. for (int i = 0; i < nrOfExamplesPerClass; i++ )
  439. {
  440. diagK(i) = kernelMatrix(i,i);
  441. }
  442. NICE::Matrix Ku (indicesOfChosenExamples.size(), nrOfExamplesPerClass, 0.0);
  443. int rowCnt(0);
  444. //set every row
  445. for (uint i = 0; i < indicesOfChosenExamples.size(); i++, rowCnt++ )
  446. {
  447. //set every element of this row
  448. NICE::Vector col = kernelMatrix.getRow(indicesOfChosenExamples[i]);
  449. for (int j = 0; j < nrOfExamplesPerClass; j++)
  450. {
  451. Ku(rowCnt,j) = col(j);
  452. }
  453. }
  454. //we could speed this up if we would order the indices
  455. NICE::Matrix Kuu (indicesOfChosenExamples.size(), indicesOfChosenExamples.size(), 0.0);
  456. double tmp(0.0);
  457. for (uint i = 0; i < indicesOfChosenExamples.size(); i++ )
  458. {
  459. for (uint j = i; j < indicesOfChosenExamples.size(); j++ )
  460. {
  461. tmp = kernelMatrix(indicesOfChosenExamples[i], indicesOfChosenExamples[j]);
  462. Kuu(i,j) = tmp;
  463. if (i != j)
  464. Kuu(j,i) = tmp;
  465. }
  466. }
  467. NICE::Vector y(nrOfExamplesPerClass,1.0); //OCC setting :)
  468. Timer tTrainPrecise;
  469. tTrainPrecise.start();
  470. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  471. {
  472. // NICE::Vector projectedLabels;
  473. // projectedLabels.multiply(Kmn,y);
  474. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  475. NICE::Matrix Luu (nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0);
  476. cr.robustChol ( Kuu, Luu );
  477. NICE::Matrix V (Ku);
  478. choleskySolveMatrixLargeScale( Luu, V);
  479. NICE::Vector dg (diagK);
  480. NICE::Vector sumV (diagK.size(),0.0);
  481. for (uint i=0; i<V.cols(); i++)
  482. {
  483. for (uint j=0; j<V.rows(); j++)
  484. {
  485. sumV(i) += V(j,i)*V(j,i);
  486. }
  487. sumV(i) += noise;
  488. }
  489. dg += sumV;
  490. for (uint i=0; i<V.cols(); i++)
  491. {
  492. for (uint j=0; j<V.rows(); j++)
  493. {
  494. V(j,i) /= sqrt(dg(i));
  495. }
  496. }
  497. NICE::Matrix Lu (indicesOfChosenExamples.size(), indicesOfChosenExamples.size(), 0.0);
  498. NICE::Matrix tmpVV (indicesOfChosenExamples.size(), indicesOfChosenExamples.size(), 0.0);
  499. tmpVV.multiply(V,V,false,true);
  500. tmpVV.addIdentity(1.0);
  501. cr.robustChol ( tmpVV, Lu );
  502. NICE::Matrix iKuu (indicesOfChosenExamples.size(), indicesOfChosenExamples.size(), 0.0);
  503. iKuu.addIdentity(1.0);
  504. choleskySolveMatrixLargeScale ( Luu.transpose(), iKuu );
  505. choleskySolveMatrixLargeScale ( Luu, iKuu );
  506. NICE::Matrix LuLuu (indicesOfChosenExamples.size(), indicesOfChosenExamples.size(), 0.0);
  507. LuLuu.multiply(Lu,Luu);
  508. choleskyMatrix.setIdentity();
  509. choleskySolveMatrixLargeScale ( LuLuu.transpose(), choleskyMatrix);
  510. choleskySolveMatrixLargeScale ( LuLuu, choleskyMatrix);
  511. choleskyMatrix -= iKuu;
  512. }
  513. tTrainPrecise.stop();
  514. std::cerr << "Precise time used for GPFITCVar training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  515. }
  516. void inline trainGPOptMean(NICE::Vector & rightPartGPOptMean, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  517. {
  518. DiagonalMatrixApprox diagApprox ( true /*verbose*/ );
  519. // rightPartGPOptMean.resize(nrOfExamplesPerClass);
  520. NICE::Matrix kInv( nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0 );
  521. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  522. Timer tTrainPrecise;
  523. tTrainPrecise.start();
  524. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  525. {
  526. cr.robustCholInv ( kernelMatrix, kInv );
  527. //we initialize the D-Matrix with the approximation we use in other methods (row sums of kernel matrix)
  528. rightPartGPOptMean.resize(nrOfExamplesPerClass);
  529. rightPartGPOptMean.set(0.0);
  530. //compute D
  531. //start with adding some noise, if necessary
  532. if (noise != 0.0)
  533. rightPartGPOptMean.set(noise);
  534. else
  535. rightPartGPOptMean.set(0.0);
  536. // the approximation creates a diagonal matrix (which is easy to invert)
  537. // with entries equal the row sums of the original kernel matrix
  538. for (int i = 0; i < nrOfExamplesPerClass; i++)
  539. {
  540. for (int j = i; j < nrOfExamplesPerClass; j++)
  541. {
  542. rightPartGPOptMean[i] += kernelMatrix(i,j);
  543. if (i != j)
  544. rightPartGPOptMean[j] += kernelMatrix(i,j);
  545. }
  546. }
  547. //compute its inverse
  548. for (int i = 0; i < nrOfExamplesPerClass; i++)
  549. {
  550. rightPartGPOptMean[i] = 1.0 / rightPartGPOptMean[i];
  551. }
  552. // rightPartGPOptMean.set(0.0);
  553. //compute optimal diagonal matrix
  554. diagApprox.approx ( kernelMatrix, rightPartGPOptMean );
  555. }
  556. tTrainPrecise.stop();
  557. std::cerr << "Precise time used for GPOptMean training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  558. }
  559. void inline trainGPOptVar(NICE::Vector & DiagGPOptVar, const double & noise, const NICE::Matrix & kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  560. {
  561. DiagonalMatrixApprox diagApprox ( true /*verbose*/ );
  562. DiagGPOptVar.resize(nrOfExamplesPerClass);
  563. NICE::Matrix kInv( nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0 );
  564. CholeskyRobust cr ( false /* verbose*/, 0.0 /*noiseStep*/, false /* useCuda*/);
  565. Timer tTrainPrecise;
  566. tTrainPrecise.start();
  567. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  568. {
  569. cr.robustCholInv ( kernelMatrix, kInv );
  570. // DiagGPOptVar.set(0.0);
  571. //we initialize the D-Matrix with the approximation we use in other methods (row sums of kernel matrix)
  572. DiagGPOptVar.resize(nrOfExamplesPerClass);
  573. DiagGPOptVar.set(0.0);
  574. //compute D
  575. //start with adding some noise, if necessary
  576. if (noise != 0.0)
  577. DiagGPOptVar.set(noise);
  578. else
  579. DiagGPOptVar.set(0.0);
  580. // the approximation creates a diagonal matrix (which is easy to invert)
  581. // with entries equal the row sums of the original kernel matrix
  582. for (int i = 0; i < nrOfExamplesPerClass; i++)
  583. {
  584. for (int j = i; j < nrOfExamplesPerClass; j++)
  585. {
  586. DiagGPOptVar[i] += kernelMatrix(i,j);
  587. if (i != j)
  588. DiagGPOptVar[j] += kernelMatrix(i,j);
  589. }
  590. }
  591. //compute its inverse
  592. for (int i = 0; i < nrOfExamplesPerClass; i++)
  593. {
  594. DiagGPOptVar[i] = 1.0 / DiagGPOptVar[i];
  595. }
  596. //compute optimal diagonal matrix
  597. diagApprox.approx ( kernelMatrix, DiagGPOptVar );
  598. }
  599. tTrainPrecise.stop();
  600. std::cerr << "Precise time used for GPOptVar training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  601. }
  602. KCMinimumEnclosingBall *trainSVDD( const double & noise, const NICE::Matrix kernelMatrix, const int & nrOfExamplesPerClass, const int & classNumber, const int & runsPerClassToAverageTraining )
  603. {
  604. Config conf;
  605. // set the outlier ratio (Paul optimized this paramter FIXME)
  606. conf.sD( "SVDD", "outlier_fraction", 0.1 );
  607. conf.sB( "SVDD", "verbose", false );
  608. KCMinimumEnclosingBall *svdd = new KCMinimumEnclosingBall ( &conf, NULL /* no kernel function */, "SVDD" /* config section */);
  609. KernelData kernelData ( &conf, kernelMatrix, "Kernel" , false /* update cholesky */ );
  610. Timer tTrainPrecise;
  611. tTrainPrecise.start();
  612. for (int run = 0; run < runsPerClassToAverageTraining; run++)
  613. {
  614. NICE::Vector y(nrOfExamplesPerClass,1.0); //OCC setting :)
  615. // KCMinimumEnclosingBall does not store the kernel data object, therefore, we are save with passing a local copy
  616. svdd->teach ( &kernelData, y );
  617. }
  618. tTrainPrecise.stop();
  619. std::cerr << "Precise time used for SVDD training class " << classNumber << ": " << tTrainPrecise.getLast()/(double)runsPerClassToAverageTraining << std::endl;
  620. return svdd;
  621. }
  622. // ------------- EVALUATION METHODS ---------------------
  623. void inline evaluateGPVarApprox(const NICE::Vector & kernelVector, const double & kernelSelf, const NICE::Vector & matrixDInv, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  624. {
  625. double uncertainty;
  626. Timer tTestSingle;
  627. tTestSingle.start();
  628. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  629. {
  630. // uncertainty = k{**} - \k_*^T \cdot D^{-1} \cdot k_* where D is our nice approximation of K
  631. NICE::Vector rightPart (kernelVector.size());
  632. for (uint j = 0; j < kernelVector.size(); j++)
  633. {
  634. rightPart[j] = kernelVector[j] * matrixDInv[j];
  635. }
  636. uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  637. }
  638. tTestSingle.stop();
  639. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  640. FullVector scores ( 2 );
  641. scores[0] = 0.0;
  642. scores[1] = 1.0 - uncertainty;
  643. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  644. }
  645. void inline evaluateGPVar(const NICE::Vector & kernelVector, const double & kernelSelf, const NICE::Matrix & choleskyMatrix, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  646. {
  647. double uncertainty;
  648. Timer tTestSingle;
  649. tTestSingle.start();
  650. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  651. {
  652. // uncertainty = k{**} - \k_*^T \cdot D^{-1} \cdot k_*
  653. NICE::Vector rightPart (kernelVector.size(),0.0);
  654. choleskySolveLargeScale ( choleskyMatrix, kernelVector, rightPart );
  655. uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  656. }
  657. tTestSingle.stop();
  658. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  659. FullVector scores ( 2 );
  660. scores[0] = 0.0;
  661. scores[1] = 1.0 - uncertainty;
  662. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  663. }
  664. void inline evaluateGPMeanApprox(const NICE::Vector & kernelVector, const NICE::Vector & rightPart, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  665. {
  666. double mean;
  667. Timer tTestSingle;
  668. tTestSingle.start();
  669. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  670. {
  671. // \mean = \k_*^T \cdot D^{-1} \cdot y where D is our nice approximation of K
  672. mean = kernelVector.scalarProduct ( rightPart );
  673. }
  674. tTestSingle.stop();
  675. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  676. FullVector scores ( 2 );
  677. scores[0] = 0.0;
  678. scores[1] = mean;
  679. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  680. }
  681. void inline evaluateGPMean(const NICE::Vector & kernelVector, const NICE::Vector & GPMeanRightPart, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  682. {
  683. double mean;
  684. Timer tTestSingle;
  685. tTestSingle.start();
  686. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  687. {
  688. // \mean = \k_*^T \cdot K^{-1} \cdot y
  689. mean = kernelVector.scalarProduct ( GPMeanRightPart );
  690. }
  691. tTestSingle.stop();
  692. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  693. FullVector scores ( 2 );
  694. scores[0] = 0.0;
  695. scores[1] = mean;
  696. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  697. }
  698. 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)
  699. {
  700. double mean;
  701. //grep the entries corresponding to the active set
  702. NICE::Vector kernelVectorM;
  703. kernelVectorM.resize(nrOfRegressors);
  704. for (int i = 0; i < nrOfRegressors; i++)
  705. {
  706. kernelVectorM[i] = kernelVector[indicesOfChosenExamples[i]];
  707. }
  708. Timer tTestSingle;
  709. tTestSingle.start();
  710. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  711. {
  712. // \mean = \k_*^T \cdot K^{-1} \cdot y
  713. mean = kernelVectorM.scalarProduct ( GPSRMeanRightPart );
  714. }
  715. tTestSingle.stop();
  716. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  717. FullVector scores ( 2 );
  718. scores[0] = 0.0;
  719. scores[1] = mean;
  720. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  721. }
  722. 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)
  723. {
  724. double uncertainty;
  725. //grep the entries corresponding to the active set
  726. NICE::Vector kernelVectorM;
  727. kernelVectorM.resize(nrOfRegressors);
  728. for (int i = 0; i < nrOfRegressors; i++)
  729. {
  730. kernelVectorM[i] = kernelVector[indicesOfChosenExamples[i]];
  731. }
  732. Timer tTestSingle;
  733. tTestSingle.start();
  734. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  735. {
  736. NICE::Vector rightPart (nrOfRegressors,0.0);
  737. choleskySolveLargeScale ( choleskyMatrix, kernelVectorM, rightPart );
  738. uncertainty = noise*kernelVectorM.scalarProduct ( rightPart );
  739. }
  740. tTestSingle.stop();
  741. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  742. FullVector scores ( 2 );
  743. scores[0] = 0.0;
  744. scores[1] = 1.0 - uncertainty;
  745. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  746. }
  747. void inline evaluateGPFITCMean(const NICE::Vector & kernelVector, const NICE::Vector & GPFITCMeanRightPart, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting, const int & nrOfRegressors, const std::vector<int> & indicesOfChosenExamples)
  748. {
  749. double mean;
  750. //grep the entries corresponding to the active set
  751. NICE::Vector kernelVectorM;
  752. kernelVectorM.resize(nrOfRegressors);
  753. for (int i = 0; i < nrOfRegressors; i++)
  754. {
  755. kernelVectorM[i] = kernelVector[indicesOfChosenExamples[i]];
  756. }
  757. Timer tTestSingle;
  758. tTestSingle.start();
  759. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  760. {
  761. // \mean = \k_*^T \cdot K^{-1} \cdot y
  762. mean = kernelVectorM.scalarProduct ( GPFITCMeanRightPart );
  763. }
  764. tTestSingle.stop();
  765. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  766. FullVector scores ( 2 );
  767. scores[0] = 0.0;
  768. scores[1] = mean;
  769. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  770. }
  771. void inline evaluateGPFITCVar(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)
  772. {
  773. double uncertainty;
  774. //grep the entries corresponding to the active set
  775. NICE::Vector kernelVectorM;
  776. kernelVectorM.resize(nrOfRegressors);
  777. for (int i = 0; i < nrOfRegressors; i++)
  778. {
  779. kernelVectorM[i] = kernelVector[indicesOfChosenExamples[i]];
  780. }
  781. Timer tTestSingle;
  782. tTestSingle.start();
  783. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  784. {
  785. NICE::Vector tmp (nrOfRegressors,0.0);
  786. tmp = choleskyMatrix*kernelVectorM;
  787. tmp *= kernelVectorM;
  788. uncertainty = 1.0 + tmp.Sum();
  789. }
  790. tTestSingle.stop();
  791. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  792. FullVector scores ( 2 );
  793. scores[0] = 0.0;
  794. scores[1] = 1.0 - uncertainty;
  795. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  796. }
  797. //this method is completely the same as evaluateGPMeanApprox, but for convenience, it is its own method
  798. void inline evaluateGPOptMean(const NICE::Vector & kernelVector, const NICE::Vector & rightPart, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  799. {
  800. double mean;
  801. Timer tTestSingle;
  802. tTestSingle.start();
  803. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  804. {
  805. // \mean = \k_*^T \cdot D^{-1} \cdot y where D is our nice approximation of K
  806. mean = kernelVector.scalarProduct ( rightPart );
  807. }
  808. tTestSingle.stop();
  809. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  810. FullVector scores ( 2 );
  811. scores[0] = 0.0;
  812. scores[1] = mean;
  813. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  814. }
  815. //this method is completely the same as evaluateGPVarApprox, but for convenience, it is its own method
  816. void inline evaluateGPOptVar(const NICE::Vector & kernelVector, const double & kernelSelf, const NICE::Vector & matrixDInv, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  817. {
  818. double uncertainty;
  819. Timer tTestSingle;
  820. tTestSingle.start();
  821. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  822. {
  823. // uncertainty = k{**} - \k_*^T \cdot D^{-1} \cdot k_* where D is our nice approximation of K
  824. NICE::Vector rightPart (kernelVector.size());
  825. for (uint j = 0; j < kernelVector.size(); j++)
  826. {
  827. rightPart[j] = kernelVector[j] * matrixDInv[j];
  828. }
  829. uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  830. }
  831. tTestSingle.stop();
  832. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  833. FullVector scores ( 2 );
  834. scores[0] = 0.0;
  835. scores[1] = 1.0 - uncertainty;
  836. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  837. }
  838. void inline evaluateParzen(const NICE::Vector & kernelVector, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  839. {
  840. double score;
  841. Timer tTestSingle;
  842. tTestSingle.start();
  843. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  844. {
  845. //the Parzen score is nothing but the averaged similarity to every training sample
  846. score = kernelVector.Sum() / (double) kernelVector.size(); //maybe we could directly call kernelVector.Mean() here
  847. }
  848. tTestSingle.stop();
  849. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  850. FullVector scores ( 2 );
  851. scores[0] = 0.0;
  852. scores[1] = score;
  853. r = ClassificationResult ( scores[1]<0.5 ? 0 : 1, scores );
  854. }
  855. void inline evaluateSVDD( KCMinimumEnclosingBall *svdd, const NICE::Vector & kernelVector, ClassificationResult & r, double & timeForSingleExamples, const int & runsPerClassToAverageTesting)
  856. {
  857. Timer tTestSingle;
  858. tTestSingle.start();
  859. for (int run = 0; run < runsPerClassToAverageTesting; run++)
  860. {
  861. // In the following, we assume that we are using a Gaussian kernel
  862. r = svdd->classifyKernel ( kernelVector, 1.0 /* kernel self */ );
  863. }
  864. tTestSingle.stop();
  865. timeForSingleExamples += tTestSingle.getLast()/(double)runsPerClassToAverageTesting;
  866. }
  867. /**
  868. test the basic functionality of fast-hik hyperparameter optimization
  869. */
  870. int main (int argc, char **argv)
  871. {
  872. std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
  873. Config conf ( argc, argv );
  874. string resultsfile = conf.gS("main", "results", "results.txt" );
  875. int nrOfExamplesPerClass = conf.gI("main", "nrOfExamplesPerClass", 50);
  876. nrOfExamplesPerClass = std::min(nrOfExamplesPerClass, 100); // we do not have more than 100 examples per class
  877. //which classes to considere? we assume consecutive class numers
  878. int indexOfFirstClass = conf.gI("main", "indexOfFirstClass", 0);
  879. indexOfFirstClass = std::max(indexOfFirstClass, 0); //we do not have less than 0 classes
  880. int indexOfLastClass = conf.gI("main", "indexOfLastClass", 999);
  881. indexOfLastClass = std::min(indexOfLastClass, 999); //we do not have more than 1000 classes
  882. int nrOfClassesToConcidere = (indexOfLastClass - indexOfLastClass)+1;
  883. //repetitions for every class to achieve reliable time evalutions
  884. int runsPerClassToAverageTraining = conf.gI( "main", "runsPerClassToAverageTraining", 1 );
  885. int runsPerClassToAverageTesting = conf.gI( "main", "runsPerClassToAverageTesting", 1 );
  886. // share parameters among methods and classes?
  887. bool shareParameters = conf.gB("main" , "shareParameters", true);
  888. //which methods do we want to use?
  889. bool GPMeanApprox = conf.gB( "main", "GPMeanApprox", false);
  890. bool GPVarApprox = conf.gB( "main", "GPVarApprox", false);
  891. bool GPMean = conf.gB( "main", "GPMean", false);
  892. bool GPVar = conf.gB( "main", "GPVar", false);
  893. bool GPSRMean = conf.gB( "main", "GPSRMean", false);
  894. bool GPSRVar = conf.gB( "main", "GPSRVar", false);
  895. bool GPFITCMean = conf.gB( "main", "GPFITCMean", false);
  896. bool GPFITCVar = conf.gB( "main", "GPFITCVar", false);
  897. bool GPOptMean = conf.gB( "main", "GPOptMean", false);
  898. bool GPOptVar = conf.gB( "main", "GPOptVar", false);
  899. bool Parzen = conf.gB( "main", "Parzen", false);
  900. bool SVDD = conf.gB( "main", "SVDD", false);
  901. if (GPMeanApprox)
  902. std::cerr << "GPMeanApprox used" << std::endl;
  903. else
  904. std::cerr << "GPMeanApprox not used" << std::endl;
  905. if (GPVarApprox)
  906. std::cerr << "GPVarApprox used" << std::endl;
  907. else
  908. std::cerr << "GPVarApprox not used" << std::endl;
  909. if (GPMean)
  910. std::cerr << "GPMean used" << std::endl;
  911. else
  912. std::cerr << "GPMean not used" << std::endl;
  913. if (GPVar)
  914. std::cerr << "GPVar used" << std::endl;
  915. else
  916. std::cerr << "GPVar not used" << std::endl;
  917. if (GPSRMean)
  918. std::cerr << "GPSRMean used" << std::endl;
  919. else
  920. std::cerr << "GPSRMean not used" << std::endl;
  921. if (GPSRVar)
  922. std::cerr << "GPSRVar used" << std::endl;
  923. else
  924. std::cerr << "GPSRVar not used" << std::endl;
  925. if (GPFITCMean)
  926. std::cerr << "GPFITCMean used" << std::endl;
  927. else
  928. std::cerr << "GPFITCMean not used" << std::endl;
  929. if (GPFITCVar)
  930. std::cerr << "GPFITCVar used" << std::endl;
  931. else
  932. std::cerr << "GPFITCVar not used" << std::endl;
  933. if (GPOptMean)
  934. std::cerr << "GPOptMean used" << std::endl;
  935. else
  936. std::cerr << "GPOptMean not used" << std::endl;
  937. if (GPOptVar)
  938. std::cerr << "GPOptVar used" << std::endl;
  939. else
  940. std::cerr << "GPOptVar not used" << std::endl;
  941. if (Parzen)
  942. std::cerr << "Parzen used" << std::endl;
  943. else
  944. std::cerr << "Parzen not used" << std::endl;
  945. if (SVDD)
  946. std::cerr << "SVDD used" << std::endl;
  947. else
  948. std::cerr << "SVDD not used" << std::endl;
  949. // GP variance approximation
  950. NICE::Vector sigmaGPVarApproxParas(nrOfClassesToConcidere,0.0);
  951. NICE::Vector noiseGPVarApproxParas(nrOfClassesToConcidere,0.0);
  952. // GP variance
  953. NICE::Vector sigmaGPVarParas(nrOfClassesToConcidere,0.0);
  954. NICE::Vector noiseGPVarParas(nrOfClassesToConcidere,0.0);
  955. //GP mean approximation
  956. NICE::Vector sigmaGPMeanApproxParas(nrOfClassesToConcidere,0.0);
  957. NICE::Vector noiseGPMeanApproxParas(nrOfClassesToConcidere,0.0);
  958. //GP mean
  959. NICE::Vector sigmaGPMeanParas(nrOfClassesToConcidere,0.0);
  960. NICE::Vector noiseGPMeanParas(nrOfClassesToConcidere,0.0);
  961. //GP SR mean
  962. NICE::Vector sigmaGPSRMeanParas(nrOfClassesToConcidere,0.0);
  963. NICE::Vector noiseGPSRMeanParas(nrOfClassesToConcidere,0.0);
  964. //GP SR var
  965. NICE::Vector sigmaGPSRVarParas(nrOfClassesToConcidere,0.0);
  966. NICE::Vector noiseGPSRVarParas(nrOfClassesToConcidere,0.0);
  967. //GP FITC mean
  968. NICE::Vector sigmaGPFITCMeanParas(nrOfClassesToConcidere,0.0);
  969. NICE::Vector noiseGPFITCMeanParas(nrOfClassesToConcidere,0.0);
  970. //GP FITC var
  971. NICE::Vector sigmaGPFITCVarParas(nrOfClassesToConcidere,0.0);
  972. NICE::Vector noiseGPFITCVarParas(nrOfClassesToConcidere,0.0);
  973. //GP Opt mean
  974. NICE::Vector sigmaGPOptMeanParas(nrOfClassesToConcidere,0.0);
  975. NICE::Vector noiseGPOptMeanParas(nrOfClassesToConcidere,0.0);
  976. //GP Opt var
  977. NICE::Vector sigmaGPOptVarParas(nrOfClassesToConcidere,0.0);
  978. NICE::Vector noiseGPOptVarParas(nrOfClassesToConcidere,0.0);
  979. //Parzen
  980. NICE::Vector sigmaParzenParas(nrOfClassesToConcidere,0.0);
  981. NICE::Vector noiseParzenParas(nrOfClassesToConcidere,0.0);
  982. //SVDD
  983. NICE::Vector sigmaSVDDParas(nrOfClassesToConcidere,0.0);
  984. NICE::Vector noiseSVDDParas(nrOfClassesToConcidere,0.0);
  985. if (!shareParameters)
  986. {
  987. //read the optimal parameters for the different methods
  988. // GP variance approximation
  989. string sigmaGPVarApproxFile = conf.gS("main", "sigmaGPVarApproxFile", "approxVarSigma.txt");
  990. string noiseGPVarApproxFile = conf.gS("main", "noiseGPVarApproxFile", "approxVarNoise.txt");
  991. // GP variance
  992. string sigmaGPVarFile = conf.gS("main", "sigmaGPVarFile", "approxVarSigma.txt");
  993. string noiseGPVarFile = conf.gS("main", "noiseGPVarFile", "approxVarNoise.txt");
  994. //GP mean approximation
  995. string sigmaGPMeanApproxFile = conf.gS("main", "sigmaGPMeanApproxFile", "approxVarSigma.txt");
  996. string noiseGPMeanApproxFile = conf.gS("main", "noiseGPMeanApproxFile", "approxVarNoise.txt");
  997. //GP mean
  998. string sigmaGPMeanFile = conf.gS("main", "sigmaGPMeanFile", "approxVarSigma.txt");
  999. string noiseGPMeanFile = conf.gS("main", "noiseGPMeanFile", "approxVarNoise.txt");
  1000. //Parzen
  1001. string sigmaParzenFile = conf.gS("main", "sigmaParzenFile", "approxVarSigma.txt");
  1002. string noiseParzenFile = conf.gS("main", "noiseParzenFile", "approxVarNoise.txt");
  1003. //SVDD
  1004. string sigmaSVDDFile = conf.gS("main", "sigmaSVDDFile", "approxVarSigma.txt");
  1005. string noiseSVDDFile = conf.gS("main", "noiseSVDDFile", "approxVarNoise.txt");
  1006. // GP variance approximation
  1007. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPVarApproxParas);
  1008. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPVarApproxParas);
  1009. // GP variance
  1010. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPVarParas);
  1011. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPVarParas);
  1012. //GP mean approximation
  1013. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPMeanApproxParas);
  1014. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPMeanApproxParas);
  1015. //GP mean
  1016. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPMeanParas);
  1017. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPMeanParas);
  1018. //GP SR mean
  1019. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPSRMeanParas);
  1020. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPSRMeanParas);
  1021. //GP SR var
  1022. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPSRVarParas);
  1023. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPSRVarParas);
  1024. //GP FITC mean
  1025. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPFITCMeanParas);
  1026. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPFITCMeanParas);
  1027. //GP FITC var
  1028. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPFITCVarParas);
  1029. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPFITCVarParas);
  1030. //GP Opt mean
  1031. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPOptMeanParas);
  1032. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPOptMeanParas);
  1033. //GP Opt var
  1034. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaGPOptVarParas);
  1035. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseGPOptVarParas);
  1036. //Parzen
  1037. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaParzenParas);
  1038. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseParzenParas);
  1039. //SVDD
  1040. readParameters(sigmaGPVarApproxFile,nrOfClassesToConcidere, sigmaSVDDParas);
  1041. readParameters(noiseGPVarApproxFile,nrOfClassesToConcidere, noiseSVDDParas);
  1042. }
  1043. else
  1044. {
  1045. //use static variables for all methods and classis
  1046. double noise = conf.gD( "main", "noise", 0.01 );
  1047. double sigma = conf.gD( "main", "sigma", 1.0 );
  1048. sigmaGPVarApproxParas.set(sigma);
  1049. noiseGPVarApproxParas.set(noise);
  1050. // GP variance
  1051. sigmaGPVarParas.set(sigma);
  1052. noiseGPVarParas.set(noise);
  1053. //GP mean approximation
  1054. sigmaGPMeanApproxParas.set(sigma);
  1055. noiseGPMeanApproxParas.set(noise);
  1056. //GP mean
  1057. sigmaGPMeanParas.set(sigma);
  1058. noiseGPMeanParas.set(noise);
  1059. //GP SR mean
  1060. sigmaGPSRMeanParas.set(sigma);
  1061. noiseGPSRMeanParas.set(noise);
  1062. //GP SR var
  1063. sigmaGPSRVarParas.set(sigma);
  1064. noiseGPSRVarParas.set(noise);
  1065. //GP FITC mean
  1066. sigmaGPFITCMeanParas.set(sigma);
  1067. noiseGPFITCMeanParas.set(noise);
  1068. //GP FITC var
  1069. sigmaGPFITCVarParas.set(sigma);
  1070. noiseGPFITCVarParas.set(noise);
  1071. //GP Opt mean
  1072. sigmaGPOptMeanParas.set(sigma);
  1073. noiseGPOptMeanParas.set(noise);
  1074. //GP Opt var
  1075. sigmaGPOptVarParas.set(sigma);
  1076. noiseGPOptVarParas.set(noise);
  1077. //Parzen
  1078. sigmaParzenParas.set(sigma);
  1079. noiseParzenParas.set(noise);
  1080. //SVDD
  1081. sigmaSVDDParas.set(sigma);
  1082. noiseSVDDParas.set(noise);
  1083. }
  1084. // -------- optimal parameters read --------------
  1085. std::vector<SparseVector> trainingData;
  1086. NICE::Vector y;
  1087. std::cerr << "Reading ImageNet data ..." << std::endl;
  1088. bool imageNetLocal = conf.gB("main", "imageNetLocal" , false);
  1089. string imageNetPath;
  1090. if (imageNetLocal)
  1091. imageNetPath = "/users2/rodner/data/imagenet/devkit-1.0/";
  1092. else
  1093. imageNetPath = "/home/dbv/bilder/imagenet/devkit-1.0/";
  1094. ImageNetData imageNetTrain ( imageNetPath + "demo/" );
  1095. imageNetTrain.preloadData( "train", "training" );
  1096. trainingData = imageNetTrain.getPreloadedData();
  1097. y = imageNetTrain.getPreloadedLabels();
  1098. std::cerr << "Reading of training data finished" << std::endl;
  1099. std::cerr << "trainingData.size(): " << trainingData.size() << std::endl;
  1100. std::cerr << "y.size(): " << y.size() << std::endl;
  1101. std::cerr << "Reading ImageNet test data files (takes some seconds)..." << std::endl;
  1102. ImageNetData imageNetTest ( imageNetPath + "demo/" );
  1103. imageNetTest.preloadData ( "val", "testing" );
  1104. imageNetTest.loadExternalLabels ( imageNetPath + "data/ILSVRC2010_validation_ground_truth.txt" );
  1105. double OverallPerformanceGPVarApprox(0.0);
  1106. double OverallPerformanceGPVar(0.0);
  1107. double OverallPerformanceGPMeanApprox(0.0);
  1108. double OverallPerformanceGPMean(0.0);
  1109. double OverallPerformanceGPSRMean(0.0);
  1110. double OverallPerformanceGPSRVar(0.0);
  1111. double OverallPerformanceGPFITCMean(0.0);
  1112. double OverallPerformanceGPFITCVar(0.0);
  1113. double OverallPerformanceGPOptMean(0.0);
  1114. double OverallPerformanceGPOptVar(0.0);
  1115. double OverallPerformanceParzen(0.0);
  1116. double OverallPerformanceSVDD(0.0);
  1117. double kernelSigmaGPVarApprox;
  1118. double kernelSigmaGPVar;
  1119. double kernelSigmaGPMeanApprox;
  1120. double kernelSigmaGPMean;
  1121. double kernelSigmaGPSRMean;
  1122. double kernelSigmaGPSRVar;
  1123. double kernelSigmaGPFITCMean;
  1124. double kernelSigmaGPFITCVar;
  1125. double kernelSigmaGPOptMean;
  1126. double kernelSigmaGPOptVar;
  1127. double kernelSigmaParzen;
  1128. double kernelSigmaSVDD;
  1129. for (int cl = indexOfFirstClass; cl <= indexOfLastClass; cl++)
  1130. {
  1131. std::cerr << "run for class " << cl << std::endl;
  1132. int positiveClass = cl+1; //labels are from 1 to 1000, but our indices from 0 to 999
  1133. // ------------------------------ TRAINING ------------------------------
  1134. kernelSigmaGPVarApprox = sigmaGPVarApproxParas[cl];
  1135. kernelSigmaGPVar = sigmaGPVarParas[cl];
  1136. kernelSigmaGPMeanApprox = sigmaGPMeanApproxParas[cl];
  1137. kernelSigmaGPMean = sigmaGPMeanParas[cl];
  1138. kernelSigmaGPSRMean = sigmaGPSRMeanParas[cl];
  1139. kernelSigmaGPSRVar = sigmaGPSRVarParas[cl];
  1140. kernelSigmaGPFITCMean = sigmaGPFITCMeanParas[cl];
  1141. kernelSigmaGPFITCVar = sigmaGPFITCVarParas[cl];
  1142. kernelSigmaGPOptMean = sigmaGPOptMeanParas[cl];
  1143. kernelSigmaGPOptVar = sigmaGPOptVarParas[cl];
  1144. kernelSigmaParzen = sigmaParzenParas[cl];
  1145. kernelSigmaSVDD = sigmaSVDDParas[cl];
  1146. Timer tTrain;
  1147. tTrain.start();
  1148. //compute the kernel matrix, which will be shared among all methods in this scenario
  1149. NICE::Matrix kernelMatrix(nrOfExamplesPerClass, nrOfExamplesPerClass, 0.0);
  1150. //NOTE in theory we have to compute a single kernel Matrix for every method, since every method may have its own optimal parameter
  1151. // I'm sure, we can speed it up a bit and compute it only for every different parameter
  1152. //nonetheless, it's not as nice as we originally thought (same matrix for every method)
  1153. //NOTE Nonetheless, since we're only interested in runtimes, we can ignore this
  1154. //now sum up all entries of each row in the original kernel matrix
  1155. double kernelScore(0.0);
  1156. for (int i = cl*100; i < cl*100+nrOfExamplesPerClass; i++)
  1157. {
  1158. for (int j = i; j < cl*100+nrOfExamplesPerClass; j++)
  1159. {
  1160. kernelScore = measureDistance(trainingData[i],trainingData[j], kernelSigmaGPVarApprox);
  1161. kernelMatrix(i-cl*100,j-cl*100) = kernelScore;
  1162. if (i != j)
  1163. kernelMatrix(j-cl*100,i-cl*100) = kernelScore;
  1164. }
  1165. }
  1166. // now call the individual training methods
  1167. //train GP Mean Approx
  1168. NICE::Vector GPMeanApproxRightPart;
  1169. if (GPMeanApprox)
  1170. trainGPMeanApprox(GPMeanApproxRightPart, noiseGPMeanApproxParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  1171. //train GP Var Approx
  1172. NICE::Vector matrixDInv;
  1173. if (GPVarApprox)
  1174. trainGPVarApprox(matrixDInv, noiseGPVarApproxParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  1175. //train GP Mean
  1176. NICE::Vector GPMeanRightPart;
  1177. if (GPMean)
  1178. trainGPMean(GPMeanRightPart, noiseGPMeanParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  1179. //train GP Var
  1180. NICE::Matrix GPVarCholesky;
  1181. if (GPVar)
  1182. trainGPVar(GPVarCholesky, noiseGPVarParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  1183. int nrOfRegressors (0);
  1184. //train GP SR Mean
  1185. NICE::Vector GPSRMeanRightPart;
  1186. std::vector<int> indicesOfChosenExamplesGPSRMean;
  1187. nrOfRegressors = conf.gI( "GPSR", "nrOfRegressors", nrOfExamplesPerClass/2);
  1188. nrOfRegressors = std::min( nrOfRegressors, nrOfExamplesPerClass );
  1189. if (GPSRMean)
  1190. trainGPSRMean(GPSRMeanRightPart, noiseGPSRMeanParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining, nrOfRegressors, indicesOfChosenExamplesGPSRMean );
  1191. //train GP SR Var
  1192. NICE::Matrix GPSRVarCholesky;
  1193. std::vector<int> indicesOfChosenExamplesGPSRVar;
  1194. if (GPSRVar)
  1195. trainGPSRVar(GPSRVarCholesky, noiseGPSRVarParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining, nrOfRegressors, indicesOfChosenExamplesGPSRVar );
  1196. //train GP FITC Mean
  1197. NICE::Vector GPFITCMeanRightPart;
  1198. std::vector<int> indicesOfChosenExamplesGPFITCMean;
  1199. nrOfRegressors = conf.gI( "GPFITC", "nrOfRegressors", nrOfExamplesPerClass/5);
  1200. nrOfRegressors = std::min( nrOfRegressors, nrOfExamplesPerClass );
  1201. if (GPFITCMean)
  1202. trainGPFITCMean(GPFITCMeanRightPart, noiseGPFITCMeanParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining, nrOfRegressors, indicesOfChosenExamplesGPFITCMean );
  1203. //train GP FITC Var
  1204. NICE::Matrix GPFITCVarCholesky;
  1205. std::vector<int> indicesOfChosenExamplesGPFITCVar;
  1206. if (GPFITCVar)
  1207. trainGPFITCVar(GPFITCVarCholesky, noiseGPFITCVarParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining, nrOfRegressors, indicesOfChosenExamplesGPFITCVar );
  1208. //train GP Opt Mean
  1209. NICE::Vector GPOptMeanRightPart;
  1210. if (GPOptMean)
  1211. trainGPOptMean(GPOptMeanRightPart, noiseGPOptMeanParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  1212. std::cerr << "GPOptMeanRightPart: " << std::endl; std::cerr << GPOptMeanRightPart << std::endl;
  1213. //train GP Opt Var
  1214. NICE::Vector DiagGPOptVar;
  1215. if (GPOptVar)
  1216. trainGPOptVar(DiagGPOptVar, noiseGPOptVarParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  1217. std::cerr << "DiagGPOptVar: " << std::endl; std::cerr << DiagGPOptVar << std::endl;
  1218. //train Parzen
  1219. //nothing to do :)
  1220. //train SVDD
  1221. KCMinimumEnclosingBall *svdd;
  1222. if (SVDD)
  1223. svdd = trainSVDD(noiseSVDDParas[cl], kernelMatrix, nrOfExamplesPerClass, cl, runsPerClassToAverageTraining );
  1224. tTrain.stop();
  1225. std::cerr << "Time used for training class " << cl << ": " << tTrain.getLast() << std::endl;
  1226. std::cerr << "training done - now perform the evaluation" << std::endl;
  1227. // ------------------------------ TESTING ------------------------------
  1228. std::cerr << "Classification step ... with " << imageNetTest.getNumPreloadedExamples() << " examples" << std::endl;
  1229. ClassificationResults resultsGPVarApprox;
  1230. ClassificationResults resultsGPVar;
  1231. ClassificationResults resultsGPMeanApprox;
  1232. ClassificationResults resultsGPMean;
  1233. ClassificationResults resultsGPSRMean;
  1234. ClassificationResults resultsGPSRVar;
  1235. ClassificationResults resultsGPFITCMean;
  1236. ClassificationResults resultsGPFITCVar;
  1237. ClassificationResults resultsGPOptMean;
  1238. ClassificationResults resultsGPOptVar;
  1239. ClassificationResults resultsParzen;
  1240. ClassificationResults resultsSVDD;
  1241. ProgressBar pb;
  1242. Timer tTest;
  1243. tTest.start();
  1244. Timer tTestSingle;
  1245. double timeForSingleExamplesGPVarApprox(0.0);
  1246. double timeForSingleExamplesGPVar(0.0);
  1247. double timeForSingleExamplesGPMeanApprox(0.0);
  1248. double timeForSingleExamplesGPMean(0.0);
  1249. double timeForSingleExamplesGPSRMean(0.0);
  1250. double timeForSingleExamplesGPSRVar(0.0);
  1251. double timeForSingleExamplesGPFITCMean(0.0);
  1252. double timeForSingleExamplesGPFITCVar(0.0);
  1253. double timeForSingleExamplesGPOptMean(0.0);
  1254. double timeForSingleExamplesGPOptVar(0.0);
  1255. double timeForSingleExamplesParzen(0.0);
  1256. double timeForSingleExamplesSVDD(0.0);
  1257. for ( uint i = 0 ; i < (uint)imageNetTest.getNumPreloadedExamples(); i++ )
  1258. {
  1259. pb.update ( imageNetTest.getNumPreloadedExamples() );
  1260. const SparseVector & svec = imageNetTest.getPreloadedExample ( i );
  1261. //NOTE: again we should use method-specific optimal parameters. If we're only interested in the runtimes, this doesn't matter
  1262. //compute (self) similarities
  1263. double kernelSelf (measureDistance(svec,svec, kernelSigmaGPVarApprox) );
  1264. NICE::Vector kernelVector (nrOfExamplesPerClass, 0.0);
  1265. for (int j = 0; j < nrOfExamplesPerClass; j++)
  1266. {
  1267. kernelVector[j] = measureDistance(trainingData[j+cl*100],svec, kernelSigmaGPVarApprox);
  1268. }
  1269. //call the individual test-methods
  1270. //evaluate GP Var Approx
  1271. ClassificationResult rGPVarApprox;
  1272. if (GPVarApprox)
  1273. evaluateGPVarApprox( kernelVector, kernelSelf, matrixDInv, rGPVarApprox, timeForSingleExamplesGPVarApprox, runsPerClassToAverageTesting );
  1274. //evaluate GP Var
  1275. ClassificationResult rGPVar;
  1276. if (GPVar)
  1277. evaluateGPVar( kernelVector, kernelSelf, GPVarCholesky, rGPVar, timeForSingleExamplesGPVar, runsPerClassToAverageTesting );
  1278. //evaluate GP Mean Approx
  1279. ClassificationResult rGPMeanApprox;
  1280. if (GPMeanApprox)
  1281. evaluateGPMeanApprox( kernelVector, matrixDInv, rGPMeanApprox, timeForSingleExamplesGPMeanApprox, runsPerClassToAverageTesting );
  1282. //evaluate GP Mean
  1283. ClassificationResult rGPMean;
  1284. if (GPMean)
  1285. evaluateGPMean( kernelVector, GPMeanRightPart, rGPMean, timeForSingleExamplesGPMean, runsPerClassToAverageTesting );
  1286. //evaluate GP SR Mean
  1287. ClassificationResult rGPSRMean;
  1288. if (GPSRMean)
  1289. evaluateGPSRMean( kernelVector, GPSRMeanRightPart, rGPSRMean, timeForSingleExamplesGPSRMean, runsPerClassToAverageTesting, nrOfRegressors, indicesOfChosenExamplesGPSRMean );
  1290. //evaluate GP SR Var
  1291. ClassificationResult rGPSRVar;
  1292. if (GPSRVar)
  1293. evaluateGPSRVar( kernelVector, GPSRVarCholesky, rGPSRVar, timeForSingleExamplesGPSRVar, runsPerClassToAverageTesting, nrOfRegressors, indicesOfChosenExamplesGPSRVar, noiseGPSRVarParas[cl] );
  1294. //evaluate GP FITC Mean
  1295. ClassificationResult rGPFITCMean;
  1296. if (GPFITCMean)
  1297. evaluateGPFITCMean( kernelVector, GPFITCMeanRightPart, rGPFITCMean, timeForSingleExamplesGPFITCMean, runsPerClassToAverageTesting, nrOfRegressors, indicesOfChosenExamplesGPFITCMean );
  1298. //evaluate GP FITC Var
  1299. ClassificationResult rGPFITCVar;
  1300. if (GPFITCVar)
  1301. evaluateGPFITCVar( kernelVector, GPFITCVarCholesky, rGPFITCVar, timeForSingleExamplesGPFITCVar, runsPerClassToAverageTesting, nrOfRegressors, indicesOfChosenExamplesGPFITCVar, noiseGPFITCVarParas[cl] );
  1302. //evaluate GP Opt Mean
  1303. ClassificationResult rGPOptMean;
  1304. if (GPOptMean)
  1305. evaluateGPOptMean( kernelVector, GPOptMeanRightPart, rGPOptMean, timeForSingleExamplesGPOptMean, runsPerClassToAverageTesting );
  1306. //evaluate GP Opt Var
  1307. ClassificationResult rGPOptVar;
  1308. if (GPOptVar)
  1309. evaluateGPOptVar( kernelVector, kernelSelf, DiagGPOptVar, rGPOptVar, timeForSingleExamplesGPOptVar, runsPerClassToAverageTesting );
  1310. //evaluate Parzen
  1311. ClassificationResult rParzen;
  1312. if (Parzen)
  1313. evaluateParzen( kernelVector, rParzen, timeForSingleExamplesParzen, runsPerClassToAverageTesting );
  1314. //evaluate SVDD
  1315. ClassificationResult rSVDD;
  1316. if (SVDD)
  1317. evaluateSVDD( svdd, kernelVector, rSVDD, timeForSingleExamplesSVDD, runsPerClassToAverageTesting );
  1318. // set ground truth label
  1319. rGPVarApprox.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1320. rGPVar.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1321. rGPMeanApprox.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1322. rGPMean.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1323. rGPSRMean.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1324. rGPSRVar.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1325. rGPFITCMean.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1326. rGPFITCVar.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1327. rGPOptMean.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1328. rGPOptVar.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1329. rParzen.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1330. rSVDD.classno_groundtruth = (((int)imageNetTest.getPreloadedLabel ( i )) == positiveClass) ? 1 : 0;
  1331. //remember the results for the evaluation lateron
  1332. resultsGPVarApprox.push_back ( rGPVarApprox );
  1333. resultsGPVar.push_back ( rGPVar );
  1334. resultsGPMeanApprox.push_back ( rGPMeanApprox );
  1335. resultsGPMean.push_back ( rGPMean );
  1336. resultsGPSRMean.push_back ( rGPSRMean );
  1337. resultsGPSRVar.push_back ( rGPSRVar );
  1338. resultsGPFITCMean.push_back ( rGPFITCMean );
  1339. resultsGPFITCVar.push_back ( rGPFITCVar );
  1340. resultsGPOptMean.push_back ( rGPOptMean );
  1341. resultsGPOptVar.push_back ( rGPOptVar );
  1342. resultsParzen.push_back ( rParzen );
  1343. resultsSVDD.push_back ( rSVDD );
  1344. }
  1345. tTest.stop();
  1346. std::cerr << "Time used for evaluating class " << cl << ": " << tTest.getLast() << std::endl;
  1347. timeForSingleExamplesGPVarApprox/= imageNetTest.getNumPreloadedExamples();
  1348. timeForSingleExamplesGPVar/= imageNetTest.getNumPreloadedExamples();
  1349. timeForSingleExamplesGPMeanApprox/= imageNetTest.getNumPreloadedExamples();
  1350. timeForSingleExamplesGPMean/= imageNetTest.getNumPreloadedExamples();
  1351. timeForSingleExamplesGPSRMean/= imageNetTest.getNumPreloadedExamples();
  1352. timeForSingleExamplesGPSRVar/= imageNetTest.getNumPreloadedExamples();
  1353. timeForSingleExamplesGPFITCMean/= imageNetTest.getNumPreloadedExamples();
  1354. timeForSingleExamplesGPFITCVar/= imageNetTest.getNumPreloadedExamples();
  1355. timeForSingleExamplesGPOptMean/= imageNetTest.getNumPreloadedExamples();
  1356. timeForSingleExamplesGPOptVar/= imageNetTest.getNumPreloadedExamples();
  1357. timeForSingleExamplesParzen/= imageNetTest.getNumPreloadedExamples();
  1358. timeForSingleExamplesSVDD/= imageNetTest.getNumPreloadedExamples();
  1359. std::cerr << "GPVarApprox -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPVarApprox << std::endl;
  1360. std::cerr << "GPVar -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPVar << std::endl;
  1361. std::cerr << "GPMeanApprox -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPMeanApprox << std::endl;
  1362. std::cerr << "GPMean -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPMean << std::endl;
  1363. std::cerr << "GPSRMean -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPSRMean << std::endl;
  1364. std::cerr << "GPSRVar -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPSRVar << std::endl;
  1365. std::cerr << "GPFITCMean -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPFITCMean << std::endl;
  1366. std::cerr << "GPFITCVar -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPFITCVar << std::endl;
  1367. std::cerr << "GPOptMean -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPOptMean << std::endl;
  1368. std::cerr << "GPOptVar -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesGPOptVar << std::endl;
  1369. std::cerr << "Parzen -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesParzen << std::endl;
  1370. std::cerr << "SVDD -- time used for evaluation single elements of class " << cl << " : " << timeForSingleExamplesSVDD << std::endl;
  1371. // run the AUC-evaluation
  1372. double perfvalueGPVarApprox( 0.0 );
  1373. double perfvalueGPVar( 0.0 );
  1374. double perfvalueGPMeanApprox( 0.0 );
  1375. double perfvalueGPMean( 0.0 );
  1376. double perfvalueGPSRMean( 0.0 );
  1377. double perfvalueGPSRVar( 0.0 );
  1378. double perfvalueGPFITCMean( 0.0 );
  1379. double perfvalueGPFITCVar( 0.0 );
  1380. double perfvalueGPOptMean( 0.0 );
  1381. double perfvalueGPOptVar( 0.0 );
  1382. double perfvalueParzen( 0.0 );
  1383. double perfvalueSVDD( 0.0 );
  1384. if (GPVarApprox)
  1385. perfvalueGPVarApprox = resultsGPVarApprox.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1386. if (GPVar)
  1387. perfvalueGPVar = resultsGPVar.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1388. if (GPMeanApprox)
  1389. perfvalueGPMeanApprox = resultsGPMeanApprox.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1390. if (GPMean)
  1391. perfvalueGPMean = resultsGPMean.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1392. if (GPSRMean)
  1393. perfvalueGPSRMean = resultsGPSRMean.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1394. if (GPSRVar)
  1395. perfvalueGPSRVar = resultsGPSRVar.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1396. if (GPFITCMean)
  1397. perfvalueGPFITCMean = resultsGPFITCMean.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1398. if (GPFITCVar)
  1399. perfvalueGPFITCVar = resultsGPFITCVar.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1400. if (GPOptMean)
  1401. perfvalueGPOptMean = resultsGPOptMean.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1402. if (GPOptVar)
  1403. perfvalueGPOptVar = resultsGPOptVar.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1404. if (Parzen)
  1405. perfvalueParzen = resultsParzen.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1406. if (SVDD)
  1407. perfvalueSVDD = resultsSVDD.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  1408. std::cerr << "Performance GPVarApprox: " << perfvalueGPVarApprox << std::endl;
  1409. std::cerr << "Performance GPVar: " << perfvalueGPVar << std::endl;
  1410. std::cerr << "Performance GPMeanApprox: " << perfvalueGPMeanApprox << std::endl;
  1411. std::cerr << "Performance GPMean: " << perfvalueGPMean << std::endl;
  1412. std::cerr << "Performance GPSRMean: " << perfvalueGPSRMean << std::endl;
  1413. std::cerr << "Performance GPSRVar: " << perfvalueGPSRVar << std::endl;
  1414. std::cerr << "Performance GPFITCMean: " << perfvalueGPFITCMean << std::endl;
  1415. std::cerr << "Performance GPFITCVar: " << perfvalueGPFITCVar << std::endl;
  1416. std::cerr << "Performance GPOptMean: " << perfvalueGPOptMean << std::endl;
  1417. std::cerr << "Performance GPOptVar: " << perfvalueGPOptVar << std::endl;
  1418. std::cerr << "Performance Parzen: " << perfvalueParzen << std::endl;
  1419. std::cerr << "Performance SVDD: " << perfvalueSVDD << std::endl;
  1420. OverallPerformanceGPVarApprox += perfvalueGPVar;
  1421. OverallPerformanceGPVar += perfvalueGPVarApprox;
  1422. OverallPerformanceGPMeanApprox += perfvalueGPMeanApprox;
  1423. OverallPerformanceGPMean += perfvalueGPMean;
  1424. OverallPerformanceGPSRMean += perfvalueGPSRMean;
  1425. OverallPerformanceGPSRVar += perfvalueGPSRVar;
  1426. OverallPerformanceGPFITCMean += perfvalueGPFITCMean;
  1427. OverallPerformanceGPFITCVar += perfvalueGPFITCVar;
  1428. OverallPerformanceGPOptMean += perfvalueGPOptMean;
  1429. OverallPerformanceGPOptVar += perfvalueGPOptVar;
  1430. OverallPerformanceParzen += perfvalueParzen;
  1431. OverallPerformanceSVDD += perfvalueSVDD;
  1432. // clean up memory used by SVDD
  1433. if (SVDD)
  1434. delete svdd;
  1435. }
  1436. OverallPerformanceGPVarApprox /= nrOfClassesToConcidere;
  1437. OverallPerformanceGPVar /= nrOfClassesToConcidere;
  1438. OverallPerformanceGPMeanApprox /= nrOfClassesToConcidere;
  1439. OverallPerformanceGPMean /= nrOfClassesToConcidere;
  1440. OverallPerformanceGPSRMean /= nrOfClassesToConcidere;
  1441. OverallPerformanceGPSRVar /= nrOfClassesToConcidere;
  1442. OverallPerformanceGPFITCMean /= nrOfClassesToConcidere;
  1443. OverallPerformanceGPFITCVar /= nrOfClassesToConcidere;
  1444. OverallPerformanceGPOptMean /= nrOfClassesToConcidere;
  1445. OverallPerformanceGPOptVar /= nrOfClassesToConcidere;
  1446. OverallPerformanceParzen /= nrOfClassesToConcidere;
  1447. OverallPerformanceSVDD /= nrOfClassesToConcidere;
  1448. std::cerr << "overall performance GPVarApprox: " << OverallPerformanceGPVarApprox << std::endl;
  1449. std::cerr << "overall performance GPVar: " << OverallPerformanceGPVar << std::endl;
  1450. std::cerr << "overall performance GPMeanApprox: " << OverallPerformanceGPMeanApprox << std::endl;
  1451. std::cerr << "overall performance GPMean: " << OverallPerformanceGPMean << std::endl;
  1452. std::cerr << "overall performance GPSRMean: " << OverallPerformanceGPSRMean << std::endl;
  1453. std::cerr << "overall performance GPSRVar: " << OverallPerformanceGPSRVar << std::endl;
  1454. std::cerr << "overall performance GPFITCMean: " << OverallPerformanceGPFITCMean << std::endl;
  1455. std::cerr << "overall performance GPFITCVar: " << OverallPerformanceGPFITCVar << std::endl;
  1456. std::cerr << "overall performance GPOptMean: " << OverallPerformanceGPOptMean << std::endl;
  1457. std::cerr << "overall performance GPOptVar: " << OverallPerformanceGPOptVar << std::endl;
  1458. std::cerr << "overall performance Parzen: " << OverallPerformanceParzen << std::endl;
  1459. std::cerr << "overall performance SVDD: " << OverallPerformanceSVDD << std::endl;
  1460. return 0;
  1461. }
  1462. #endif