completeEvaluationFastMinkernel.cpp 9.3 KB

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