completeEvaluationFastMinkernel.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /**
  2. * @file completeEvaluationFastMinkernel.cpp
  3. * @brief Demo-Program to show how to call some methods of the FastMinKernel class
  4. * @author Alexander Freytag
  5. * @date 12/08/2011
  6. */
  7. #include <vector>
  8. #include <iostream>
  9. #include <cstdlib>
  10. #include <ctime>
  11. #include "core/vector/MatrixT.h"
  12. #include "core/vector/VectorT.h"
  13. #include "gp-hik-core/FastMinKernel.h"
  14. #include "gp-hik-core/tools.h"
  15. #include "gp-hik-core/VectorSorter.h"
  16. #include "gp-hik-core/FeatureMatrixT.h"
  17. #include "gp-hik-core/kernels/IntersectionKernelFunction.h"
  18. using namespace std;
  19. using namespace NICE;
  20. /**
  21. * @brief Printing main menu.
  22. * @author Alexander Freytag
  23. * @date 12/06/2011
  24. *
  25. * @return void
  26. **/
  27. void print_main_menu()
  28. {
  29. std::cerr << "===============================================================================================================" << std::endl;
  30. std::cerr << "|| Welcome to the evaluation programm for our FastMinKernel class ||" << std::endl;
  31. std::cerr << "|| ||" << std::endl;
  32. std::cerr << "|| We will run some tests to evaluate the efficiency of our fast computations compared to the baseline ones. ||" << std::endl;
  33. std::cerr << "|| Note, that the benefit is larger for higher number of dimensions. ||" << std::endl;
  34. std::cerr << "|| Note further, that we randomly sample features, wherefore the results might differ from run to run. ||" << std::endl;
  35. std::cerr << "|| Finally, note that in practical applications the speed-up is larger due to sparse features. ||" << std::endl;
  36. std::cerr << "===============================================================================================================" << std::endl;
  37. std::cout << std::endl << "Input options:" << std::endl;
  38. std::cout << " -n <number> number of examples to generate (optional)"<< std::endl;
  39. std::cout << " -d <number> number of dimensions for each example"<< std::endl;
  40. std::cout << " -v 1/0 verbose mode (optional)"<< std::endl;
  41. return;
  42. }
  43. int main (int argc, char* argv[])
  44. {
  45. std::cout.precision(15);
  46. std::cerr.precision(15);
  47. int nEx (5);
  48. int d (10);
  49. bool verbose(false);
  50. bool nGiven (false);
  51. int rc;
  52. if (argc<2)
  53. {
  54. print_main_menu();
  55. return -1;
  56. }
  57. while ((rc=getopt(argc,argv,"n:d:v:h"))>=0)
  58. {
  59. switch(rc)
  60. {
  61. case 'n':
  62. {
  63. nEx = atoi(optarg);
  64. nGiven = true;
  65. break;
  66. }
  67. case 'd': d = atoi(optarg); break;
  68. case 'v': verbose = atoi(optarg); break;
  69. default: print_main_menu();
  70. }
  71. }
  72. srand ( time(NULL) );
  73. std::vector<int> trainingSizes; trainingSizes.clear();
  74. std::vector<int> dataDimensions; dataDimensions.clear();
  75. std::vector<float> timePreparationEfficiently; timePreparationEfficiently.clear();
  76. std::vector<float> timeMultiplicationEfficiently; timeMultiplicationEfficiently.clear();
  77. std::vector<float> timePreparationSlowly; timePreparationSlowly.clear();
  78. std::vector<float> timeMultiplicationSlowly; timeMultiplicationSlowly.clear();
  79. std::vector<float> timeKSumEfficiently; timeKSumEfficiently.clear();
  80. std::vector<float> timeKSumSlowly; timeKSumSlowly.clear();
  81. std::vector<double> errorsMultiplication; errorsMultiplication.clear();
  82. std::vector<double> errorsKSum; errorsKSum.clear();
  83. int lower (1000);
  84. int upper(10000);
  85. int stepSize(1000);
  86. if (nGiven)
  87. {
  88. lower = nEx;
  89. upper = nEx;
  90. }
  91. for (int n = lower; n <= upper; n+=stepSize)
  92. {
  93. if (verbose)
  94. std::cerr << "================================" << std::endl;
  95. std::cerr << "n: " << n << std::endl;
  96. trainingSizes.push_back(n);
  97. dataDimensions.push_back(d);
  98. //generate random data with specified dimensions and number of examples
  99. std::vector<std::vector<double> > rand_feat;
  100. generateRandomFeatures(d,n,rand_feat);
  101. //transpose the data structure so that it fits to our fastHIK struct
  102. std::vector<std::vector<double> > rand_feat_transposed (rand_feat);
  103. transposeVectorOfVectors(rand_feat_transposed);
  104. //generate random alpha vectors
  105. Vector alphas;
  106. generateRandomFeatures(n, alphas);
  107. //for these experiments, the noise does not matter
  108. double noise (0.0);
  109. //---------------- EVALUATE THE RUNTIME needed for initializing both methods (fast-hik vs baseline) ---------------------------
  110. time_t hik_efficient_preparation_start = clock();
  111. FastMinKernel fastHIK ( rand_feat, noise );
  112. NICE::VVector A;
  113. NICE::VVector B;
  114. fastHIK.hik_prepare_alpha_multiplications(alphas, A, B);
  115. float time_hik_efficient_preparation = (float) (clock() - hik_efficient_preparation_start);
  116. if (verbose)
  117. {
  118. std::cerr << "Time for HIK efficient preparation: " << time_hik_efficient_preparation/CLOCKS_PER_SEC << std::endl;
  119. }
  120. timePreparationEfficiently.push_back(time_hik_efficient_preparation/CLOCKS_PER_SEC);
  121. //---------------- EVALUATE THE ERROR AND RUNTIME FOR MULTIPLY K \alpha (aka kernel_multiply) ---------------------------
  122. Vector beta;
  123. //tic
  124. time_t hik_multiply_start = clock();
  125. fastHIK.hik_kernel_multiply(A, B, alphas, beta);
  126. //toc
  127. float time_hik_multiply = (float) (clock() - hik_multiply_start);
  128. if (verbose)
  129. {
  130. std::cerr << "Time for HIK multiplication: " << time_hik_multiply/CLOCKS_PER_SEC << std::endl;
  131. }
  132. timeMultiplicationEfficiently.push_back(time_hik_multiply/CLOCKS_PER_SEC);
  133. NICE::IntersectionKernelFunction<double> hikSlow;
  134. //tic
  135. time_t hik_slow_prepare_start = clock();
  136. NICE::Matrix K (hikSlow.computeKernelMatrix(rand_feat_transposed, noise));
  137. //toc
  138. float time_hik_slow_prepare = (float) (clock() - hik_slow_prepare_start);
  139. if (verbose)
  140. {
  141. std::cerr << "Time for HIK slow preparation of Kernel Matrix: " << time_hik_slow_prepare/CLOCKS_PER_SEC << std::endl;
  142. }
  143. timePreparationSlowly.push_back(time_hik_slow_prepare/CLOCKS_PER_SEC);
  144. time_t hik_slow_multiply_start = clock();
  145. Vector betaSlow = K*alphas;
  146. //toc
  147. float time_hik_slow_multiply = (float) (clock() - hik_slow_multiply_start);
  148. if (verbose)
  149. {
  150. std::cerr << "Time for HIK slow multiply: " << time_hik_slow_multiply/CLOCKS_PER_SEC << std::endl;
  151. }
  152. timeMultiplicationSlowly.push_back(time_hik_slow_multiply/CLOCKS_PER_SEC);
  153. Vector diff = beta - betaSlow;
  154. double error = diff.normL2();
  155. errorsMultiplication.push_back(error);
  156. if (verbose)
  157. {
  158. std::cerr << "error: " << error << std::endl;
  159. }
  160. //---------------- EVALUATE THE ERROR AND RUNTIME FOR COMPUTING k_* \alpha (aka kernel_sum) ---------------------------
  161. Vector xstar;
  162. generateRandomFeatures(d, xstar);
  163. double kSum;
  164. //tic
  165. time_t hik_ksum_start = clock();
  166. fastHIK.hik_kernel_sum(A, B, xstar, kSum);
  167. //toc
  168. float time_hik_ksum = (float) (clock() - hik_ksum_start);
  169. if (verbose)
  170. std::cerr << "Time for HIK efficient kSum: " << time_hik_ksum/CLOCKS_PER_SEC << std::endl;
  171. timeKSumEfficiently.push_back(time_hik_ksum/CLOCKS_PER_SEC);
  172. if (verbose)
  173. {
  174. std::cerr << "kSum efficiently: " << kSum << std::endl;
  175. }
  176. //tic
  177. time_t hik_ksum_slowly_start = clock();
  178. std::vector<double> xstar_stl (d, 0.0);
  179. for (int i = 0; i < d; i++)
  180. {
  181. xstar_stl[i] = xstar[i];
  182. }
  183. Vector kstarSlow ( hikSlow.computeKernelVector(rand_feat_transposed, xstar_stl));
  184. xstar.resize(xstar_stl.size());
  185. for ( int i = 0 ; i < xstar.size() ; i++ )
  186. xstar[i] = xstar_stl[i];
  187. double kSumSlowly = alphas.scalarProduct(kstarSlow);
  188. //toc
  189. float time_hik_slowly_ksum = (float) (clock() - hik_ksum_slowly_start);
  190. if (verbose)
  191. std::cerr << "Time for HIK slowly kSum: " << time_hik_slowly_ksum/CLOCKS_PER_SEC << std::endl;
  192. timeKSumSlowly.push_back(time_hik_slowly_ksum/CLOCKS_PER_SEC);
  193. if (verbose)
  194. {
  195. std::cerr << "kSumSlowly: " << kSumSlowly << std::endl;
  196. }
  197. double kSumError( fabs(kSumSlowly - kSum));
  198. errorsKSum.push_back(kSumError);
  199. if (verbose)
  200. std::cerr << "kSumError: " << kSumError << std::endl;
  201. }
  202. //---------------- FINAL OUTPUT ---------------------------
  203. std::cerr << std::endl << "n - d - timePreparationEfficiently - timeMultiplicationEfficiently - timePreparationSlowly - timeMultiplicationSlowly - timeKSumEfficiently - timeKSumSlowly" << std::endl;
  204. for (int i = 0; i < (int) trainingSizes.size(); i++)
  205. {
  206. std::cerr << trainingSizes[i] << " ";
  207. std::cerr << dataDimensions[i] << " ";
  208. std::cerr << timePreparationEfficiently[i] << " ";
  209. std::cerr << timeMultiplicationEfficiently[i] << " ";
  210. std::cerr << timePreparationSlowly[i] << " ";
  211. std::cerr << timeMultiplicationSlowly[i] << " ";
  212. std::cerr << timeKSumEfficiently[i] << " ";
  213. std::cerr << timeKSumSlowly[i] << " ";
  214. std::cerr << std::endl;
  215. }
  216. std::cerr << std::endl << "n - d - errorMultiplication - errorsKSum" << std::endl;
  217. for (int i = 0; i < (int) trainingSizes.size(); i++)
  218. {
  219. std::cerr << trainingSizes[i] << " ";
  220. std::cerr << dataDimensions[i] << " ";
  221. std::cerr << errorsMultiplication[i] << " ";
  222. std::cerr << errorsKSum[i] << " ";
  223. std::cerr << std::endl;
  224. }
  225. return 0;
  226. }