eval.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #include "eval.h"
  2. #include <algorithm>
  3. #include <assert.h>
  4. #include <iostream>
  5. #include <iomanip>
  6. using namespace std;
  7. namespace Tn
  8. {
  9. float evalTopResult(list<vector<float>>& result,list<int>& groundTruth,int* TP /*= nullptr*/,int* FP /*= nullptr*/,int topK /*= 1*/)
  10. {
  11. int _TP = TP ? *TP: 0;
  12. int _FP = FP ? *FP: 0;
  13. assert(result.size() == groundTruth.size());
  14. auto pRe = result.begin();
  15. auto pGT = groundTruth.begin();
  16. for (; pRe != result.end() && pGT != groundTruth.end();
  17. ++pRe, ++pGT)
  18. {
  19. auto& labels = *pRe;
  20. int truthClass = *pGT;
  21. float gtProb = labels[truthClass];
  22. int biggerCount = 0;
  23. for (auto& prob : labels)
  24. {
  25. if (prob >= gtProb)
  26. ++biggerCount;
  27. }
  28. biggerCount > topK ? ++_FP : ++_TP;
  29. }
  30. float accuracy=float(_TP)/(_TP+_FP);
  31. if(TP) *TP =_TP;
  32. if(FP) *FP =_FP;
  33. mTensorIvlog->info("top: %d, accuracy: %d, %f", topK, setprecision(4), accuracy);
  34. // cout<<"top " << topK <<" accuracy :"<< setprecision(4) << accuracy << endl;
  35. return accuracy;
  36. }
  37. float iou_compute(const Bbox& a,const Bbox& b)
  38. {
  39. int and_right=min(a.right,b.right);
  40. int and_left =max(a.left,b.left);
  41. int and_top =max(a.top,b.top);
  42. int and_bot =min(a.bot,b.bot);
  43. if ((and_top>and_bot) || (and_left>and_right))
  44. {
  45. return 0.0f;
  46. }
  47. float sand=(and_right-and_left)*(and_bot-and_top)*1.0f;
  48. float sa=(a.right-a.left)*(a.bot-a.top)*1.0f;
  49. float sb=(b.right-b.left)*(b.bot-b.top)*1.0f;
  50. float iou=sand/(sa+sb-sand);
  51. return iou;
  52. }
  53. float evalMAPResult(const list<vector<Bbox>>& bboxesList,const list<vector<Bbox>>& truthboxesList,int classNum,float iouThresh)
  54. {
  55. assert(bboxesList.size() == truthboxesList.size());
  56. mTensorIvlog->info("svalMAPResult:");
  57. // cout << "evalMAPResult:" << endl;
  58. float* precision = new float[classNum];
  59. float* recall = new float[classNum];
  60. float* AP = new float[classNum]{};
  61. vector<Bbox> **detBox = nullptr;
  62. vector<Bbox> **truthBox = nullptr;
  63. int sampleCount = bboxesList.size();
  64. detBox = new vector<Bbox>* [sampleCount];
  65. truthBox = new vector<Bbox>* [sampleCount];
  66. for (int i = 0 ;i < sampleCount ; ++ i)
  67. {
  68. detBox[i] = new vector<Bbox>[classNum]{};
  69. truthBox[i] = new vector<Bbox>[classNum]{};
  70. }
  71. auto pBoxIter = bboxesList.begin();
  72. auto pTrueIter = truthboxesList.begin();
  73. for (int i = 0;i< sampleCount;++i , ++pBoxIter , ++pTrueIter)
  74. {
  75. for (const auto& item : *pBoxIter)
  76. detBox[i][item.classId].push_back(item);
  77. for (const auto& item : *pTrueIter)
  78. truthBox[i][item.classId].push_back(item);
  79. }
  80. for (int i = 0;i < classNum; ++ i)
  81. {
  82. using CheckPair = pair<Bbox,bool>;
  83. vector< CheckPair > checkPRBoxs;
  84. int FN = 0;
  85. for (int j = 0;j< sampleCount;++j)
  86. {
  87. auto& dboxes = detBox[j][i];
  88. auto& tboxes = truthBox[j][i];
  89. auto checkTBoxes = tboxes;
  90. for (const auto& item: dboxes)
  91. {
  92. int maxIdx = -1;
  93. float maxIou = 0;
  94. for (const auto& tItem: checkTBoxes)
  95. {
  96. float iou=iou_compute(item,tItem);
  97. //std::cout << "iou" << iou << std::endl;
  98. if(iou > maxIou)
  99. {
  100. maxIdx = &tItem - &checkTBoxes[0];
  101. maxIou = iou;
  102. }
  103. }
  104. if(maxIou > iouThresh)
  105. {
  106. checkPRBoxs.push_back({item,true});
  107. checkTBoxes.erase(checkTBoxes.begin() + maxIdx);
  108. }
  109. else
  110. {
  111. //FP
  112. checkPRBoxs.push_back({item,false});
  113. }
  114. }
  115. //FN
  116. FN += checkTBoxes.size();
  117. }
  118. float TP = count_if(checkPRBoxs.begin(), checkPRBoxs.end(), [](CheckPair& item){return item.second == true;} );
  119. int total = checkPRBoxs.size();
  120. if(total == 0)
  121. {
  122. AP[i] = FN > 0 ? 0 : 1;
  123. continue;
  124. }
  125. //recall:
  126. recall[i] = (abs(TP + FN) < 1e-5) ? 1 : TP / (TP + FN);
  127. //precision
  128. precision[i] = TP / total;
  129. //compute AP:
  130. sort(checkPRBoxs.begin(),checkPRBoxs.end(),[](CheckPair& left,CheckPair& right){
  131. return left.first.score > right.first.score;
  132. }
  133. );
  134. int PR_TP = 0;
  135. int PR_FP = 0;
  136. vector< pair<float,float> > PRValues; //<P,R>
  137. for (const auto& item : checkPRBoxs)
  138. {
  139. item.second ? ++PR_TP : ++PR_FP;
  140. PRValues.emplace_back( make_pair(PR_TP/ float(PR_TP+PR_FP) , PR_TP / float(total)) );
  141. }
  142. float sum = PRValues[0].first * PRValues[0].second;
  143. for (unsigned int m = 0; m < PRValues.size()-1;++m)
  144. {
  145. float w = PRValues[m + 1].second - PRValues[m].second ;
  146. float h = PRValues[m + 1].first;
  147. sum += w*h;
  148. }
  149. AP[i] = sum;
  150. mTensorIvlog->info("%d class: %d %d iou thresh-%f AP:%d %f recall:%d %f precision:%d %f", \
  151. setprecision(4), std::setw(3), i, iouThresh, std::setw(7), AP[i], \
  152. std::setw(7), recall[i], setw(7), precision[i]);
  153. // cout<< setprecision(4) << "class:" << std::setw(3) << i
  154. // << " iou thresh-" << iouThresh
  155. // << " AP:" << std::setw(7) << AP[i]
  156. // << " recall:" << std::setw(7) << recall[i]
  157. // << " precision:" << std::setw(7) << precision[i] << endl;
  158. }
  159. float sumAp = 0;
  160. for (int i = 0;i < classNum;++i)
  161. sumAp += AP[i];
  162. float MAP = sumAp / classNum;
  163. mTensorIvlog->info("MAP: %f", MAP);
  164. // cout<< "MAP:" << MAP << endl;
  165. if (precision)
  166. delete[] precision;
  167. if (recall)
  168. delete[] recall;
  169. if (AP)
  170. delete[] AP;
  171. for (int i = 0;i < sampleCount; ++i)
  172. {
  173. delete[] detBox[i];
  174. delete[] truthBox[i];
  175. }
  176. delete[] detBox;
  177. delete[] truthBox;
  178. return MAP;
  179. }
  180. }