RangiLyu / nanodet

NanoDet-Plusāš”Super fast and lightweight anchor-free object detection model. šŸ”„Only 980 KB(int8) / 1.8MB (fp16) and run 97FPS on cellphonešŸ”„
Apache License 2.0
5.78k stars 1.04k forks source link

NCNN - Bounding box is slightly off for NanoDet-m but is correct for NanoDet-Plus-m #456

Open dpetersonVT23 opened 2 years ago

dpetersonVT23 commented 2 years ago

When running the demo_ncnn script with a model, I observe NanoDet-Plus-m performs as expected, but NanoDet-m has a bounding box that is slightly to the left and slightly higher than it should be every single time (the .pth performs fine though). I removed one of the strides in the header file, is there anything else I need to do for NanoDet-m specifically in the demo_ncnn module?

stiansel commented 2 years ago

The non-plus model has a 0.5 offset in the output grid. This may not be accounted for in that inference script's output decoding. See this part of the code in the regular Nanodet: https://github.com/RangiLyu/nanodet/blob/0f4d8f114431d80729c900c158708b7d70ee2384/nanodet/model/head/gfl_head.py#L650 vs this part in plus: https://github.com/RangiLyu/nanodet/blob/0f4d8f114431d80729c900c158708b7d70ee2384/nanodet/model/head/nanodet_plus_head.py#L492

cyizhuo commented 12 months ago

The non-plus model has a 0.5 offset in the output grid. This may not be accounted for in that inference script's output decoding. See this part of the code in the regular Nanodet:

https://github.com/RangiLyu/nanodet/blob/0f4d8f114431d80729c900c158708b7d70ee2384/nanodet/model/head/gfl_head.py#L650

vs this part in plus: https://github.com/RangiLyu/nanodet/blob/0f4d8f114431d80729c900c158708b7d70ee2384/nanodet/model/head/nanodet_plus_head.py#L492

Thx, stiansel!

I solved this bbox shifting problem by following steps:

Step 1:

change code in nanodet/nanodet/model/head/gfl_head.py around line 656-657 from

x_range = (torch.arange(w, dtype=dtype, device=device) + 0.5) * stride
y_range = (torch.arange(h, dtype=dtype, device=device) + 0.5) * stride

to

# x_range = (torch.arange(w, dtype=dtype, device=device) + 0.5) * stride
# y_range = (torch.arange(h, dtype=dtype, device=device) + 0.5) * stride
x_range = (torch.arange(w, dtype=dtype, device=device)) * stride
y_range = (torch.arange(h, dtype=dtype, device=device)) * stride

Step 2:

train model

Step 3:

convert pytorch model to onnx, then to ncnn, then problem solved!