FPCCascade.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /**
  2. * @file FPCCascade.cpp
  3. * @brief abstract interface for a classifier using feature selection
  4. * @author Erik Rodner
  5. * @date 04/21/2008
  6. */
  7. #include <iostream>
  8. #include "FPCCascade.h"
  9. using namespace OBJREC;
  10. using namespace std;
  11. // refactor-nice.pl: check this substitution
  12. // old: using namespace ice;
  13. using namespace NICE;
  14. const int maxCascades = 9999;
  15. FPCCascade::FPCCascade( FeaturePoolClassifier *_classifier,
  16. int _backgroundClass )
  17. : classifier(_classifier),
  18. backgroundClass (_backgroundClass),
  19. nextComplexity (0)
  20. {
  21. }
  22. FPCCascade::~FPCCascade()
  23. {
  24. for ( Cascade::iterator i = cascade.begin(); i != cascade.end(); i++ )
  25. {
  26. delete i->second;
  27. }
  28. delete classifier;
  29. }
  30. double shiftedSigmoid ( double x )
  31. {
  32. const double alpha = 100.0;
  33. return 1/(1+exp(-(x-0.5)*alpha));
  34. }
  35. #if 0
  36. void calibrateProb ( SparseVector & scores, double T, int backgroundClass )
  37. {
  38. for ( SparseVector::iterator i = scores.begin();
  39. i != scores.end();
  40. i++ )
  41. {
  42. if ( i->first == backgroundClass ) {
  43. if ( i->second < T )
  44. i->second *= 0.5 / T;
  45. else
  46. i->second = 0.5 * (i->second - T) / (1.0 - T) + 0.5;
  47. } else {
  48. if ( i->second < 1.0-T )
  49. i->second *= 0.5 / (1.0-T);
  50. else
  51. i->second = 0.5 * (i->second - 1.0 + T) / T + 0.5;
  52. }
  53. i->second = shiftedSigmoid ( i->second );
  54. }
  55. scores.normalize();
  56. }
  57. #endif
  58. ClassificationResult FPCCascade::classify ( Example & pe )
  59. {
  60. FullVector overall_scores;
  61. bool rejected = false;
  62. int cindex = 0;
  63. for ( Cascade::const_iterator i = cascade.begin();
  64. (i != cascade.end()) && (cindex < maxCascades);
  65. i++,cindex++ )
  66. {
  67. ClassificationResult r = i->second->classify ( pe );
  68. double threshold = i->first;
  69. if ( overall_scores.empty() )
  70. overall_scores = r.scores;
  71. else
  72. overall_scores.add ( r.scores );
  73. double score = overall_scores.get(backgroundClass) / overall_scores.sum();
  74. if ( score > threshold ) {
  75. rejected = true;
  76. break;
  77. }
  78. }
  79. overall_scores.normalize();
  80. int overall_classno = 0;
  81. overall_classno = rejected ? backgroundClass : overall_scores.maxElementExclusive( backgroundClass );
  82. assert ( !(!rejected && (overall_classno == backgroundClass) ) );
  83. return ClassificationResult ( overall_classno, overall_scores );
  84. }
  85. void FPCCascade::train ( FeaturePool & fp, Examples & examples )
  86. {
  87. maxClassNo = examples.getMaxClassNo();
  88. fprintf (stderr, "FPCCascade: adding new cascade %d\n", (int)cascade.size() + 1 );
  89. FeaturePoolClassifier *c = classifier->clone();
  90. c->maxClassNo = maxClassNo;
  91. if ( nextComplexity >= 0 )
  92. c->setComplexity ( nextComplexity );
  93. c->train ( fp, examples );
  94. cascade.push_back ( pair<double, FeaturePoolClassifier *> ( 0.5, c ) );
  95. }
  96. void FPCCascade::restore (istream & is, int format)
  97. {
  98. // refactor-nice.pl: check this substitution
  99. // old: string tag;
  100. std::string tag;
  101. classifier->maxClassNo = maxClassNo;
  102. fprintf (stderr, "FPCCascade: max classno %d\n", maxClassNo );
  103. while ( (is >> tag) && (tag == "WEAKCLASSIFIER") )
  104. {
  105. FeaturePoolClassifier *c = classifier->clone();
  106. double threshold;
  107. is >> threshold;
  108. c->restore ( is );
  109. cascade.push_back ( pair<double, FeaturePoolClassifier *>
  110. ( threshold, c ) );
  111. }
  112. }
  113. void FPCCascade::store (ostream & os, int format) const
  114. {
  115. for ( Cascade::const_iterator i = cascade.begin();
  116. i != cascade.end();
  117. i++ )
  118. {
  119. const FeaturePoolClassifier *classifier = i->second;
  120. double threshold = i->first;
  121. os << "WEAKCLASSIFIER" << endl;
  122. os << threshold << endl;
  123. classifier->store (os);
  124. os << "ENDWEAKCLASSIFIER" << endl;
  125. }
  126. }
  127. void FPCCascade::deleteLastClassifier ()
  128. {
  129. FeaturePoolClassifier *c = cascade.back().second;
  130. delete c;
  131. cascade.pop_back();
  132. }
  133. FeaturePoolClassifier *FPCCascade::getLastClassifier ()
  134. {
  135. return cascade.back().second;
  136. }
  137. void FPCCascade::clear ()
  138. {
  139. cascade.clear();
  140. }
  141. FPCCascade *FPCCascade::clone () const
  142. {
  143. FeaturePoolClassifier *classifierClone = classifier->clone();
  144. classifierClone->maxClassNo = maxClassNo;
  145. FPCCascade *cascadeClone = new FPCCascade ( classifierClone, backgroundClass );
  146. cascadeClone->maxClassNo = maxClassNo;
  147. cascadeClone->nextComplexity = nextComplexity;
  148. return cascadeClone;
  149. }
  150. void FPCCascade::setLastThreshold ( double threshold )
  151. {
  152. assert ( cascade.size() > 0 );
  153. cascade.back().first = threshold;
  154. }
  155. void FPCCascade::setComplexity ( int size )
  156. {
  157. nextComplexity = size;
  158. }