mv_machine_learning: code refactoring to GetClassficationResults
authorInki Dae <inki.dae@samsung.com>
Thu, 11 Aug 2022 01:31:43 +0000 (10:31 +0900)
committerInki Dae <inki.dae@samsung.com>
Fri, 2 Sep 2022 08:09:25 +0000 (17:09 +0900)
[Issue type] code cleanup

Did code refactoring to GetClassficationResults functions by doing,
- drop logs from computing relevant funtions due to performance
  eating issue.
- use FillOutputResult function instead of
  mOutputTensorBuffers.getValue() which is performance eating function
  because it tries to find tensor buffer with a given layer name
  for every iteration.
- and also drop the code smell, code duplication.

This patch is just a step for next code refactoring. Which in turn,
FillOuputResult function will be refactored soon in generic way
including dropping the performance eating functions.

Change-Id: I4d8779001143a569f2f76664511005e7fcd8b389
Signed-off-by: Inki Dae <inki.dae@samsung.com>
mv_machine_learning/inference/src/Inference.cpp
mv_machine_learning/inference/src/PostProcess.cpp

index 1616ace5377028dc2e8f1bbcdca32344c0905bab..478cd17fcc3fb8709d033a8f2d3362cc5321f504 100755 (executable)
@@ -1098,6 +1098,19 @@ namespace inference
                // Will contain top N results in ascending order.
                std::vector<std::pair<float, int>> topScore;
                auto threadHold = mConfig.mConfidenceThresHold;
+               constexpr unsigned int default_top_number = 5;
+               tensor_t outputData;
+
+               // Get inference result and contain it to outputData.
+               int ret = FillOutputResult(outputData);
+               if (ret != MEDIA_VISION_ERROR_NONE) {
+                       LOGE("Fail to get output result.");
+                       return ret;
+               }
+
+               PostProcess postProc;
+               unsigned int classes = outputData.dimInfo[0][1];
+               unsigned int top_number = default_top_number;
 
                if (mMetadata.GetOutputMeta().IsParsed()) {
                        OutputMetadata outputMetadata = mMetadata.GetOutputMeta();
@@ -1108,27 +1121,28 @@ namespace inference
                                return MEDIA_VISION_ERROR_INVALID_OPERATION;
                        }
 
-                       int classes = mOutputLayerProperty.layers[outputMetadata.GetScoreName()].shape[indexes[0]];
-
                        if (!mOutputTensorBuffers.exist(outputMetadata.GetScoreName())) {
                                LOGE("output buffe is NULL");
                                return MEDIA_VISION_ERROR_INVALID_OPERATION;
                        }
 
-                       PostProcess postProc;
-
-                       postProc.ScoreClear(outputMetadata.GetScoreTopNumber());
+                       top_number = outputMetadata.GetScoreTopNumber();
                        threadHold = outputMetadata.GetScoreThreshold();
 
-                       for (int cId = 0; cId < classes; ++cId) {
-                               float value = 0.0f;
+                       classes = mOutputLayerProperty.layers[outputMetadata.GetScoreName()].shape[indexes[0]];
+               }
 
-                               try {
-                                       value = mOutputTensorBuffers.getValue<float>(outputMetadata.GetScoreName(), cId);
-                               } catch (const std::exception& e) {
-                                       LOGE(" Fail to get getValue with %s", e.what());
-                                       return MEDIA_VISION_ERROR_INVALID_OPERATION;
-                               }
+               postProc.ScoreClear(top_number);
+
+               auto *prediction = reinterpret_cast<float *>(outputData.data[0]);
+
+               LOGI("class count: %d", classes);
+
+               for (unsigned int idx = 0; idx < classes; ++idx) {
+                       float value = prediction[idx];
+
+                       if (mMetadata.GetOutputMeta().IsParsed()) {
+                               OutputMetadata outputMetadata = mMetadata.GetOutputMeta();
 
                                if (outputMetadata.GetScoreDeQuant()) {
                                        value = PostProcess::dequant(value,
@@ -1138,59 +1152,15 @@ namespace inference
 
                                if (outputMetadata.GetScoreType() == INFERENCE_SCORE_TYPE_SIGMOID)
                                        value = PostProcess::sigmoid(value);
-
-                               if (value < threadHold)
-                                       continue;
-
-                               LOGI("id[%d]: %.3f", cId, value);
-                               postProc.ScorePush(value, cId);
                        }
 
-                       postProc.ScorePop(topScore);
-               } else {
-                       tensor_t outputData;
-
-                       // Get inference result and contain it to outputData.
-                       int ret = FillOutputResult(outputData);
-                       if (ret != MEDIA_VISION_ERROR_NONE) {
-                               LOGE("Fail to get output result.");
-                               return ret;
-                       }
-
-                       auto classes = outputData.dimInfo[0][1];
-                       auto *prediction = reinterpret_cast<float *>(outputData.data[0]);
-
-                       LOGI("class count: %d", classes);
-
-                       std::priority_queue<std::pair<float, int>,
-                                                               std::vector<std::pair<float, int>>,
-                                                               std::greater<std::pair<float, int>>>
-                                       top_result_pq;
-
-                       for (int cId = 0; cId < classes; ++cId) {
-                               auto value = prediction[cId];
-
-                               if (value < threadHold)
-                                       continue;
-
-                               // Only add it if it beats the threshold and has a chance at being in
-                               // the top N.
-                               top_result_pq.push(std::pair<float, int>(value, cId));
-
-                               // If at capacity, kick the smallest value out.
-                               if (top_result_pq.size() > static_cast<size_t>(mConfig.mMaxOutputNumbers))
-                                       top_result_pq.pop();
-                       }
-
-                       // Copy to output vector and reverse into descending order.
-                       while (!top_result_pq.empty()) {
-                               topScore.push_back(top_result_pq.top());
-                               top_result_pq.pop();
-                       }
+                       if (value < threadHold)
+                               continue;
 
-                       std::reverse(topScore.begin(), topScore.end());
+                       postProc.ScorePush(value, idx);
                }
 
+               postProc.ScorePop(topScore);
                results->number_of_classes = 0;
 
                for (auto& score : topScore) {
index b3a4a962650f645e8bb7668b01d76a8aa9fbf591..c7335b34656e4fce5427e2d4fc4046ee22f604d9 100755 (executable)
@@ -33,44 +33,31 @@ namespace inference
 
        float PostProcess::dequant(float value, float scale, float zeropoint)
        {
-               LOGI("ENTER");
-
-               LOGI("LEAVE");
                return value/scale + zeropoint;
        }
 
        int PostProcess::ScoreClear(int size)
        {
-               LOGI("ENTER");
-
                std::priority_queue<std::pair<float, int>,
                                                        std::vector<std::pair<float, int>>,
                                                        std::greater<std::pair<float, int>>>().swap(mScore);
                mMaxScoreSize = size;
 
-               LOGI("LEAVE");
-
                return MEDIA_VISION_ERROR_NONE;
        }
 
        int PostProcess::ScorePush(float value, int index)
        {
-               LOGI("ENTER");
-
                mScore.push(std::pair<float, int>(value, index));
                if (mScore.size() > (size_t)mMaxScoreSize) {
                        mScore.pop();
                }
 
-               LOGI("LEAVE");
-
                return MEDIA_VISION_ERROR_NONE;
        }
 
        int PostProcess::ScorePop(std::vector<std::pair<float, int>>& top)
        {
-               LOGI("ENTER");
-
                top.clear();
                while (!mScore.empty()) {
                        top.push_back(mScore.top());
@@ -80,8 +67,6 @@ namespace inference
 
                std::reverse(top.begin(), top.end());
 
-               LOGI("LEAVE");
-
                return MEDIA_VISION_ERROR_NONE;
        }