eccv2012-synthetic.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. /**
  2. * @file eccv2012-synthetic.cpp
  3. * @brief ECCV 2012 Experiment with synthetic histograms to show the possibility of feature relevance selection
  4. * @author Alexander Freytag
  5. * @date 17-02-2012 (dd-mm-yyyy)
  6. */
  7. // STL includes
  8. #include <vector>
  9. #include <fstream>
  10. #include <iostream>
  11. #include <sstream>
  12. #include <limits>
  13. // NICE-core includes
  14. #include <core/basics/vectorio.h>
  15. #include <core/basics/Config.h>
  16. #include <core/basics/numerictools.h>
  17. #include <core/basics/Timer.h>
  18. //
  19. #include <core/image/Histogram.h>
  20. //
  21. #include <core/vector/VectorT.h>
  22. // NICE-vislearning includes
  23. #include <vislearning/cbaselib/ClassificationResults.h>
  24. // gp-hik-core includes
  25. #include <gp-hik-core/FastMinKernel.h>
  26. #include <gp-hik-core/FMKGPHyperparameterOptimization.h>
  27. //
  28. #include <gp-hik-core/parameterizedFunctions/PFAbsExp.h>
  29. #include <gp-hik-core/parameterizedFunctions/PFExp.h>
  30. #include <gp-hik-core/parameterizedFunctions/PFWeightedDim.h>
  31. //
  32. #include <gp-hik-core/tools.h>
  33. using namespace std;
  34. using namespace NICE;
  35. using namespace OBJREC;
  36. void sampleDataOneExample(std::vector<double> & trainData, const int & classNr)
  37. {
  38. double sum(0.0);
  39. double h1,h2,h3,h4,h5,h6,h7,h8;
  40. if (classNr == 1)
  41. {
  42. while (true)
  43. {
  44. h1 = fabs(randGaussDouble(0.03)); sum += h1;
  45. h2 = randDouble(0.25); sum += h2;
  46. h3 = fabs(randGaussDouble(0.07)); sum += h3;
  47. h4 = fabs(randGaussDouble(0.05)); sum += h4;
  48. h5 = randDouble(0.25); sum += h5;
  49. h6 = randDouble(0.25); sum += h6;
  50. h7 = randDouble(0.25); sum += h7;
  51. if (sum <= 1.0) // if sum is smaller than 1.0, everything is ok
  52. break;
  53. sum = 0.0;
  54. }
  55. h8 = 1.0-sum;
  56. }
  57. else
  58. {
  59. while (true)
  60. {
  61. h1 = randDouble(0.25); sum += h1;
  62. h2 = fabs(randGaussDouble(0.07)); sum += h2;
  63. h3 = fabs(randGaussDouble(0.12)); sum += h3;
  64. h4 = fabs(randGaussDouble(0.05)); sum += h4;
  65. h5 = randDouble(0.25); sum += h5;
  66. h6 = randDouble(0.25); sum += h6;
  67. h7 = randDouble(0.25); sum += h7;
  68. if (sum <= 1.0) // if sum is smaller than 1.0, everything is ok
  69. break;
  70. sum = 0.0;
  71. }
  72. h8 = 1.0-sum;
  73. }
  74. trainData.push_back(h1);
  75. trainData.push_back(h2);
  76. trainData.push_back(h3);
  77. trainData.push_back(h4);
  78. trainData.push_back(h5);
  79. trainData.push_back(h6);
  80. trainData.push_back(h7);
  81. trainData.push_back(h8);
  82. }
  83. void sampleData(std::vector< std::vector<double> > & trainData, NICE::Vector & y, const int & nrExamplesPerClass)
  84. {
  85. // initRand();
  86. trainData.clear();
  87. y.resize(2*nrExamplesPerClass);
  88. for (int i = 0; i < nrExamplesPerClass; i++)
  89. {
  90. //sample positive example
  91. y[2*i] = 1;
  92. std::vector<double> trainDataOneExample;
  93. sampleDataOneExample(trainDataOneExample, 1);
  94. trainData.push_back(trainDataOneExample);
  95. //sample negative example
  96. trainDataOneExample.clear();
  97. y[2*i+1] = -1;
  98. sampleDataOneExample(trainDataOneExample, -1);
  99. trainData.push_back(trainDataOneExample);
  100. }
  101. }
  102. void evaluateRandomDistribution(const std::vector< std::vector<double> > & trainData, const NICE::Vector & y, std::vector<NICE::Histogram> & histograms)
  103. {
  104. histograms.resize(16); // 8 dimensions in this synthetic example for two classes
  105. //init
  106. for (int i = 0; i < 16; i++)
  107. {
  108. histograms[i] = NICE::Histogram ( 0.0, 0.25, 10 ); // min, max, numberBins
  109. }
  110. histograms[0] = NICE::Histogram ( 0.0, 0.25, 10 );
  111. histograms[3] = NICE::Histogram ( 0.0, 0.25, 10 );
  112. histograms[9] = NICE::Histogram ( 0.0, 0.25, 10 );
  113. histograms[11] = NICE::Histogram ( 0.0, 0.25, 10 );
  114. histograms[7] = NICE::Histogram ( 0.0, 1.0, 10 );
  115. histograms[15] = NICE::Histogram ( 0.0, 1.0, 10 );
  116. for (int i = 0; i < 16; i++)
  117. {
  118. histograms[i].set(0);
  119. }
  120. //start
  121. int clAdd(0);
  122. for (int i = 0; i < trainData.size(); i++)
  123. {
  124. // std::cerr << i << " / " << trainData.size() << std::endl;
  125. //evaluation for the first class
  126. if (y[i] == 1)
  127. {
  128. histograms[0].increaseBin((int)floor(trainData[i][0]*40));
  129. histograms[1].increaseBin((int)floor(trainData[i][1]*40));
  130. histograms[2].increaseBin((int)floor(trainData[i][2]*40));
  131. histograms[3].increaseBin((int)floor(trainData[i][3]*40));
  132. histograms[4].increaseBin((int)floor(trainData[i][4]*40));
  133. histograms[5].increaseBin((int)floor(trainData[i][5]*40));
  134. histograms[6].increaseBin((int)floor(trainData[i][6]*40));
  135. histograms[7].increaseBin((int)floor(trainData[i][7]*10));
  136. }
  137. else //evaluation for the second class
  138. {
  139. histograms[8].increaseBin((int)floor(trainData[i][0]*40));
  140. histograms[9].increaseBin((int)floor(trainData[i][1]*40));
  141. histograms[10].increaseBin((int)floor(trainData[i][2]*40));
  142. histograms[11].increaseBin((int)floor(trainData[i][3]*40));
  143. histograms[12].increaseBin((int)floor(trainData[i][4]*40));
  144. histograms[13].increaseBin((int)floor(trainData[i][5]*40));
  145. histograms[14].increaseBin((int)floor(trainData[i][6]*40));
  146. histograms[15].increaseBin((int)floor(trainData[i][7]*10));
  147. }
  148. }
  149. }
  150. /**
  151. ECCV 2012 Experiment with synthetic data
  152. */
  153. int main (int argc, char **argv)
  154. {
  155. std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
  156. initRand();
  157. Config conf ( argc, argv );
  158. Config confBaseline ( conf );
  159. confBaseline.sS("HIKGP", "optimization_method", "none");
  160. string pf_baseline_s = conf.gS("main", "transformBaseline", "absexp");
  161. string pf_featRel_s = conf.gS("main", "transformFeatRel", "weightedDim");
  162. int nrRuns = conf.gI("main", "nrRuns", 1);
  163. int testSize = conf.gI("main", "testSize", 150); // per category
  164. bool printRandomDistribution = conf.gB("main", "printRandomDistribution", false);
  165. confBaseline.sD( "FMKGPHyperparameterOptimization", "parameter_upper_bound", numeric_limits<double>::max( ) );
  166. confBaseline.sD( "FMKGPHyperparameterOptimization", "parameter_lower_bound", numeric_limits<double>::min( ) );
  167. if ( pf_baseline_s == "absexp" )
  168. confBaseline.sS( "FMKGPHyperparameterOptimization", "transform", "absexp" );
  169. else if ( pf_baseline_s == "exp" )
  170. confBaseline.sS( "FMKGPHyperparameterOptimization", "transform", "exp" );
  171. else
  172. fthrow(Exception, "Parameterized function type " << pf_baseline_s << " not yet implemented");
  173. conf.sD( "FMKGPHyperparameterOptimization", "parameter_upper_bound", numeric_limits<double>::max( ) );
  174. conf.sD( "FMKGPHyperparameterOptimization", "parameter_lower_bound", numeric_limits<double>::min( ) );
  175. conf.sS( "FMKGPHyperparameterOptimization", "transform", "weightedDim" );
  176. int dim ( 8 );
  177. conf.sI( "FMKGPHyperparameterOptimization", "pf_dim", dim );
  178. std::cerr << "Transformation type baseline: " << pf_baseline_s << std::endl;
  179. std::cerr << "Transformation type FeatRel: " << pf_featRel_s << std::endl;
  180. std::vector<int> trainSizes; // per category
  181. // trainSizes.push_back(5);
  182. // trainSizes.push_back(10);
  183. // trainSizes.push_back(15);
  184. // trainSizes.push_back(20);
  185. // trainSizes.push_back(50);
  186. // trainSizes.push_back(75);
  187. // trainSizes.push_back(100);
  188. trainSizes.push_back(500);
  189. std::vector<std::vector<double> > ARRs_baseline;
  190. std::vector<std::vector<double> > ARRs_featRel;
  191. std::vector<std::vector<double> > AUCs_baseline;
  192. std::vector<std::vector<double> > AUCs_featRel;
  193. for (std::vector<int>::const_iterator trainSize = trainSizes.begin(); trainSize != trainSizes.end(); trainSize++)
  194. {
  195. std::cerr << "trainSize: " << *trainSize << std::endl;
  196. double AARRBaseline(0.0); // averaged average recognition rate :)
  197. double AARRFeatRel(0.0); // averaged average recognition rate :)
  198. double AAUCBaseline(0.0); // averaged area under curve :)
  199. double AAUCFeatRel(0.0); // averaged area under curve :)
  200. std::vector<double> ARRs_baseline_SingleSize;
  201. std::vector<double> ARRs_featRel_SingleSize;
  202. std::vector<double> AUCs_baseline_SingleSize;
  203. std::vector<double> AUCs_featRel_SingleSize;
  204. for (int run = 0; run < nrRuns; run++)
  205. {
  206. std::cerr << "run: " << run << std::endl;
  207. //----------------- TRAINING -------------------------
  208. //sample the training data
  209. std::vector< std::vector<double> > trainData;
  210. NICE::Vector yTrain;
  211. sampleData(trainData,yTrain, *trainSize);
  212. if (printRandomDistribution)
  213. {
  214. std::vector<double> borders;
  215. borders.push_back(0.25);borders.push_back(0.25);borders.push_back(0.25);borders.push_back(0.25);borders.push_back(0.25);borders.push_back(0.25);borders.push_back(0.25);borders.push_back(1.0);borders.push_back(0.25);borders.push_back(0.25);borders.push_back(0.25);borders.push_back(0.25);borders.push_back(0.25);borders.push_back(0.25);borders.push_back(0.25);borders.push_back(1.0);
  216. std::cerr << "print distribution of features " << std::endl;
  217. std::vector<NICE::Histogram> histograms;
  218. evaluateRandomDistribution(trainData, yTrain, histograms);
  219. for (int i = 0; i < histograms.size(); i++)
  220. {
  221. int sum (0);
  222. std::string fn = "/home/luetz/code/fast-hik/nice/fast-hik/hist";
  223. std::stringstream s1;
  224. s1 << i/8;
  225. fn += s1.str();
  226. fn += "-";
  227. std::stringstream s2;
  228. s2 << i%8;
  229. fn += s2.str();
  230. std::cerr << "filename: "<< fn.c_str() << std::endl;
  231. std::fstream outfile;
  232. outfile.open( fn.c_str(), ios::out );
  233. if (outfile.is_open())
  234. {
  235. for (int k = 0; k < histograms[i].bins(); k++)
  236. {
  237. outfile << borders[i]*k/ (double)histograms[i].bins() << " " << histograms[i][k] << std::endl;
  238. sum += histograms[i][k];
  239. }
  240. outfile.close();
  241. }
  242. else{
  243. std::cerr << "error while opening file " << fn << std::endl;
  244. }
  245. }
  246. std::cerr << "ending the function, we only printed the distributions" << std::endl;
  247. return 0;
  248. }
  249. std::vector<double> meanValues;
  250. calculateMeanPerDimension(trainData, meanValues);
  251. transposeVectorOfVectors ( trainData );
  252. //baseline without feature relevance
  253. double noise = 0.1;
  254. FastMinKernel *fmkBaseline = new FastMinKernel ( trainData, noise );
  255. FMKGPHyperparameterOptimization hyperBaseline ( &confBaseline, fmkBaseline );
  256. hyperBaseline.optimize ( yTrain );
  257. //with optimization of feature relevance (= optimization of weights for each dimension)
  258. FastMinKernel *fmkFeatRel = new FastMinKernel ( trainData, noise, dim );
  259. // std::cerr << "print Parameter of pfWeightedDim" << std::endl;
  260. // std::cerr << pfFeatRel->parameters() << std::endl;
  261. // std::cerr << "print Matrix after transformation" << std::endl;
  262. // pfFeatRel->applyFunctionToFeatureMatrix(fmkFeatRel->featureMatrix());
  263. // fmkFeatRel->featureMatrix().print();
  264. FMKGPHyperparameterOptimization hyperFeatRel ( &conf, fmkFeatRel, "FMKGPHyperparameterOptimization" /*config section*/ );
  265. hyperFeatRel.optimize ( yTrain );
  266. std::cerr << "meanValues: ";
  267. for (std::vector<double>::const_iterator meanIt = meanValues.begin(); meanIt != meanValues.end(); meanIt++)
  268. {
  269. std::cerr << *meanIt << " ";
  270. }
  271. std::cerr << std::endl << std::endl;
  272. //----------------- TESTING -------------------------
  273. //sample the training data
  274. std::vector< std::vector<double> > testData;
  275. NICE::Vector yTest;
  276. sampleData(testData,yTest, testSize);
  277. // std::cerr << "Printing testData: " << std::endl;
  278. // printMatrix<double>(testData);
  279. // std::cerr << yTest << std::endl;
  280. Timer t;
  281. Matrix confusionBaseline ( 2, 2, 0.0 );
  282. Matrix confusionFeatRel ( 2, 2, 0.0 );
  283. ClassificationResults resultsBaseline;
  284. ClassificationResults resultsFeatRel;
  285. for ( uint i = 0 ; i < testData.size(); i++ )
  286. {
  287. const Vector xstar(testData[i]);
  288. // the following is just to be sure that we
  289. // do not count the time necessary for conversion
  290. SparseVector xstar_sparse ( xstar ); //default tolerance is 10e-10
  291. int classno_groundtruth = yTest[i];
  292. //dirty :(
  293. if ((classno_groundtruth) < 0)
  294. classno_groundtruth = 0;
  295. SparseVector scoresBaseline;
  296. t.start();
  297. uint classno_estimated_baseline = hyperBaseline.classify ( xstar_sparse, scoresBaseline );
  298. t.stop();
  299. scoresBaseline.store(cerr);
  300. cerr << "baseline [" << i << " / " << testData.size() << "] " << classno_estimated_baseline << " " << classno_groundtruth << " time: " << t.getLast() << endl;
  301. confusionBaseline( classno_groundtruth, classno_estimated_baseline ) += 1;
  302. // building the result
  303. ClassificationResult rBaseline ( classno_estimated_baseline, scoresBaseline );
  304. // set ground truth label
  305. rBaseline.classno_groundtruth = classno_groundtruth;
  306. resultsBaseline.push_back ( rBaseline );
  307. SparseVector scoresFeatRel;
  308. t.start();
  309. uint classno_estimated_featRel = hyperFeatRel.classify ( xstar_sparse, scoresFeatRel );
  310. t.stop();
  311. scoresFeatRel.store(cerr);
  312. cerr << "FeatRel [" << i << " / " << testData.size() << "] " << classno_estimated_featRel << " " << classno_groundtruth << " time: " << t.getLast() << endl;
  313. confusionFeatRel( classno_groundtruth, classno_estimated_featRel ) += 1;
  314. // building the result
  315. ClassificationResult rFeatRel ( classno_estimated_featRel, scoresFeatRel );
  316. // set ground truth label
  317. rFeatRel.classno_groundtruth = classno_groundtruth;
  318. resultsFeatRel.push_back ( rFeatRel );
  319. }
  320. confusionBaseline.normalizeRowsL1();
  321. confusionFeatRel.normalizeRowsL1();
  322. // --------------- ARR evaluation --------------------
  323. cerr << confusionBaseline << endl;
  324. cerr << "average recognition rate baseline: " << confusionBaseline.trace()/confusionBaseline.rows() << endl;
  325. cerr << confusionFeatRel << endl;
  326. cerr << "average recognition rate featRel: " << confusionFeatRel.trace()/confusionFeatRel.rows() << endl;
  327. AARRBaseline += (confusionBaseline.trace()/confusionBaseline.rows()) / nrRuns;
  328. ARRs_baseline_SingleSize.push_back(confusionBaseline.trace()/confusionBaseline.rows());
  329. AARRFeatRel += (confusionFeatRel.trace()/confusionFeatRel.rows()) / nrRuns;
  330. ARRs_featRel_SingleSize.push_back(confusionFeatRel.trace()/confusionFeatRel.rows());
  331. // --------------- AUC evaluation --------------------
  332. double perfvalueBaseline = resultsBaseline.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  333. cerr << "AUC Baseline: " << perfvalueBaseline << endl;
  334. double perfvalueFeatRel = resultsFeatRel.getBinaryClassPerformance( ClassificationResults::PERF_AUC );
  335. cerr << "AUC FeatRel: " << perfvalueFeatRel << endl;
  336. AAUCBaseline += perfvalueBaseline / nrRuns;
  337. AUCs_baseline_SingleSize.push_back(perfvalueBaseline);
  338. AAUCFeatRel += perfvalueFeatRel / nrRuns;
  339. AUCs_featRel_SingleSize.push_back(perfvalueFeatRel);
  340. }
  341. ARRs_baseline.push_back(ARRs_baseline_SingleSize);
  342. ARRs_featRel.push_back(ARRs_featRel_SingleSize);
  343. AUCs_baseline.push_back(AUCs_baseline_SingleSize);
  344. AUCs_featRel.push_back(AUCs_featRel_SingleSize);
  345. }
  346. std::cerr << "================ EVALUATION ARR======================== " << std::endl;
  347. std::cerr << "trainsize << meanBaseline << stdDevBaseline << meanFeatRel << stdDevFeatRel " << std::endl;
  348. for (uint trainSizeIdx = 0; trainSizeIdx < trainSizes.size(); trainSizeIdx++)
  349. {
  350. double meanBaseline( calculating_mean(ARRs_baseline[trainSizeIdx]) );
  351. double meanFeatRel( calculating_mean(ARRs_featRel[trainSizeIdx]) );
  352. double stdDevBaseline(calculating_std_dev(ARRs_baseline[trainSizeIdx], meanBaseline));
  353. double stdDevFeatRel(calculating_std_dev(ARRs_featRel[trainSizeIdx], meanFeatRel));
  354. std::cerr << trainSizes[trainSizeIdx] << " " << meanBaseline << " " << stdDevBaseline << " " << meanFeatRel << " " << stdDevFeatRel << std::endl;
  355. }
  356. std::cerr << std::endl << std::endl << "================ EVALUATION AUC======================== " << std::endl;
  357. std::cerr << "trainsize << meanBaseline << stdDevBaseline << meanFeatRel << stdDevFeatRel " << std::endl;
  358. for (uint trainSizeIdx = 0; trainSizeIdx < trainSizes.size(); trainSizeIdx++)
  359. {
  360. double meanBaseline( calculating_mean(AUCs_baseline[trainSizeIdx]) );
  361. double meanFeatRel( calculating_mean(AUCs_featRel[trainSizeIdx]) );
  362. double stdDevBaseline(calculating_std_dev(AUCs_baseline[trainSizeIdx], meanBaseline));
  363. double stdDevFeatRel(calculating_std_dev(AUCs_featRel[trainSizeIdx], meanFeatRel));
  364. std::cerr << trainSizes[trainSizeIdx] << " " << meanBaseline << " " << stdDevBaseline << " " << meanFeatRel << " " << stdDevFeatRel << std::endl;
  365. }
  366. return 0;
  367. }