FPCCascade.cpp 4.5 KB

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