nanodet icon indicating copy to clipboard operation
nanodet copied to clipboard

Difference between ncnn and pytorch postprocessing

Open haujulian opened this issue 1 year ago • 7 comments

Hello, thank you for your work! In my tests the ncnn version produces slightly worse results compared to the pytorch version. I assume this is the case because of the different postprocessing. Is there a reason for those changes, and is it possible to get the same results using ncnn?

haujulian avatar Apr 10 '23 11:04 haujulian

Hello @HauJulian, were you able to figure this out? I am facing the same issue as well.

PaVaNTrIpAtHi avatar May 08 '23 13:05 PaVaNTrIpAtHi

Sadly not. For now I am using the results as they are, but I am still interested if someone comes up with a solution.

haujulian avatar May 09 '23 13:05 haujulian

I was able to solve it. My problem was that the confidence value of my detections were difference in python and cpp. It was sometimes >200 in CPP. In case you are facing this issue, you can use the changes which I used. We actually have to pass the output through sigmoid function to get the right results. I changed the decode_infer function and added sigmoid function to the scores and it helped me in my case. image

for (int label = 0; label < this->num_class; label++) { if (sigmoid(scores[label]) > score) { score = sigmoid(scores[label]); cur_label = label; } }

PaVaNTrIpAtHi avatar May 17 '23 15:05 PaVaNTrIpAtHi

Do you get exactly the same detections? For me it sadly does not help as sigmoid is already applied in the onnx file.

haujulian avatar May 18 '23 12:05 haujulian

also check if your config file has this parameter, keep_ratio: False.

If this is the case, you will have to change main.cpp

image

    dst = cv::Mat(cv::Size(dst_w, dst_h), CV_8UC3, cv::Scalar(0));

    float ratio_src = w * 1.0 / h;
    // float ratio_dst = dst_w * 1.0 / dst_h;  //comment this line and add the below line
    float ratio_dst = ratio_src;

    int tmp_w = 0;
    int tmp_h = 0;
    if (ratio_src > ratio_dst) {
        tmp_w = dst_w;
        tmp_h = floor((dst_w * 1.0 / w) * h);
    }
    else if (ratio_src < ratio_dst) {
        tmp_h = dst_h;
        tmp_w = floor((dst_h * 1.0 / h) * w);
    }
    else {
        cv::resize(src, dst, dst_size);
        effect_area.x = 0;
        effect_area.y = 0;
        effect_area.width = dst_w;
        effect_area.height = dst_h;
        return 0;
    }


PaVaNTrIpAtHi avatar May 19 '23 10:05 PaVaNTrIpAtHi

You are right. That improved my results. Thanks! But my results are still about 1-2% worse compared to pytorch inference. May I ask what thresholds you use for the postprocessing?

haujulian avatar May 19 '23 20:05 haujulian

I fixed my threshold using hit and trial method. Check which particular values are giving you the best results and fix them as per that. Happy to see that it was solved on your end too.

PaVaNTrIpAtHi avatar May 21 '23 10:05 PaVaNTrIpAtHi