KCGPLaplaceOneVsAll.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /**
  2. * @file KCGPLaplaceOneVsAll.cpp
  3. * @brief One vs. All interface for kernel classifiers
  4. * @author Erik Rodner
  5. * @date 12/10/2009
  6. */
  7. #include <iostream>
  8. #include <sstream>
  9. #include "core/vector/Algorithms.h"
  10. #include "core/optimization/limun/OptimizationAlgorithmFirst.h"
  11. #include "core/optimization/limun/FirstOrderTrustRegion.h"
  12. #include "core/optimization/limun/FirstOrderRasmussen.h"
  13. #include "vislearning/classifier/kernelclassifier/GPLaplaceOptimizationProblem.h"
  14. #include "core/algebra/CholeskyRobust.h"
  15. #include "core/algebra/CholeskyRobustAuto.h"
  16. #include "KCGPLaplaceOneVsAll.h"
  17. #include "LHCumulativeGauss.h"
  18. using namespace std;
  19. using namespace NICE;
  20. using namespace OBJREC;
  21. KCGPLaplaceOneVsAll::KCGPLaplaceOneVsAll( const Config *conf, Kernel *kernelFunction, const string & section )
  22. : KernelClassifier ( conf, kernelFunction ),
  23. // we have to copy the config to initialize Laplace Approximation stuff
  24. confCopy(*conf),
  25. confSection(section)
  26. {
  27. this->maxClassNo = 0;
  28. this->verbose = conf->gB( section, "verbose", false );
  29. this->optimizeParameters = (kernelFunction == NULL) ? false : conf->gB( section, "optimize_parameters", true );
  30. this->maxIterations = conf->gI( section, "optimization_maxiterations", 500 );
  31. // the only one supported by now
  32. likelihoodFunction = new LHCumulativeGauss( conf->gD(section, "likelihood_lengthscale", sqrt(2)) );
  33. useLooParameters = conf->gB( section, "use_loo_parameters", false );
  34. }
  35. KCGPLaplaceOneVsAll::~KCGPLaplaceOneVsAll()
  36. {
  37. if ( likelihoodFunction != NULL )
  38. delete likelihoodFunction;
  39. if ( laplaceApproximations.size() != 0 )
  40. {
  41. for ( uint i = 0 ; i < laplaceApproximations.size(); i++ )
  42. delete laplaceApproximations[i];
  43. laplaceApproximations.clear();
  44. }
  45. }
  46. void KCGPLaplaceOneVsAll::teach ( KernelData *kernelData, const NICE::Vector & y )
  47. {
  48. maxClassNo = (int)y.Max();
  49. // FIXME: This code is still not suitable for settings
  50. // with missing classes between 0..maxClassNo
  51. classnos.resize(maxClassNo+1);
  52. for ( int i = 0 ; i <= maxClassNo ; i++ )
  53. {
  54. NICE::Vector ySubZeroMean ( y.size() );
  55. for ( size_t j = 0 ; j < y.size() ; j++ )
  56. ySubZeroMean[j] = ((int)y[j] == i) ? 1 : -1;
  57. ySetZeroMean.push_back ( ySubZeroMean );
  58. classnos[i] = i;
  59. }
  60. if ( laplaceApproximations.size() != 0 )
  61. {
  62. for ( uint i = 0 ; i < laplaceApproximations.size(); i++ )
  63. delete laplaceApproximations[i];
  64. laplaceApproximations.clear();
  65. }
  66. for ( uint k = 0 ; k < ySetZeroMean.size(); k++ )
  67. laplaceApproximations.push_back ( new LaplaceApproximation ( &confCopy, confSection ) );
  68. // Hyperparameter optimization
  69. if ( optimizeParameters )
  70. {
  71. ParameterizedKernel *kernelPara = dynamic_cast< ParameterizedKernel * > ( kernelFunction );
  72. if ( kernelPara == NULL ) {
  73. fthrow(Exception, "KCGPLaplaceOneVsAll: you have to specify a parameterized kernel !");
  74. }
  75. GPLaplaceOptimizationProblem gpopt ( kernelData, ySetZeroMean, kernelPara, likelihoodFunction, laplaceApproximations, verbose );
  76. // the trust region classifier is better for my large collection of one classification problem :)
  77. // FirstOrderRasmussen optimizer;
  78. FirstOrderTrustRegion optimizer;
  79. optimizer.setMaxIterations ( maxIterations );
  80. optimizer.setEpsilonG ( 0.01 );
  81. cout << "KCGPLaplaceOneVsAll: Hyperparameter optimization ..." << endl;
  82. optimizer.optimizeFirst ( gpopt );
  83. cout << "KCGPLaplaceOneVsAll: Hyperparameter optimization ...done" << endl;
  84. if ( useLooParameters )
  85. {
  86. cerr << "KCGPLaplaceOneVsAll: using best loo parameters" << endl;
  87. gpopt.useLooParameters();
  88. }
  89. gpopt.update();
  90. Vector parameters;
  91. kernelPara->getParameters ( parameters );
  92. cout << "KCGPLaplaceOneVsAll: Optimization finished: " << parameters << endl << endl;
  93. } else {
  94. kernelData->updateCholeskyFactorization();
  95. for ( uint i = 0 ; i < ySetZeroMean.size() ; i++ )
  96. {
  97. const Vector & ySubZeroMean = ySetZeroMean[i];
  98. fprintf (stderr, "KCGPLaplaceOneVsAll: training classifier class %d <-> remainder\n", i );
  99. laplaceApproximations[i]->approximate ( kernelData, ySubZeroMean, likelihoodFunction );
  100. }
  101. }
  102. }
  103. ClassificationResult KCGPLaplaceOneVsAll::classifyKernel ( const NICE::Vector & kernelVector, double kernelSelf ) const
  104. {
  105. if ( laplaceApproximations.size() <= 0 )
  106. fthrow(Exception, "The classifier was not trained with training data (use teach(...))");
  107. FullVector scores ( maxClassNo+1 );
  108. scores.set(0);
  109. uint k = 0;
  110. for ( vector< LaplaceApproximation* >::const_iterator i =
  111. laplaceApproximations.begin(); i != laplaceApproximations.end(); i++,k++ )
  112. {
  113. int classno = classnos[k];
  114. double yEstimate = (*i)->predict(kernelVector, kernelSelf, ySetZeroMean[k], likelihoodFunction);
  115. for ( uint j = 0 ; j < classnos.size(); j++ )
  116. if ( classnos[j] == classno )
  117. scores[classnos[j]] += yEstimate;
  118. else
  119. scores[classnos[j]] += 1.0 - yEstimate;
  120. }
  121. scores.multiply( 1.0/laplaceApproximations.size() );
  122. return ClassificationResult( scores.maxElement(), scores );
  123. }