YOLOV5_NCNN_Android icon indicating copy to clipboard operation
YOLOV5_NCNN_Android copied to clipboard

how to replaced the input with a downscaled image and stacked it to match the channel number?

Open panchengl opened this issue 4 years ago • 36 comments

hey, I modified the code in the common.py file, but the predicted boxes are all wrong after the conversion the in the mobile devices. Do I need to modify other parameters? thank U

panchengl avatar Jul 23 '20 07:07 panchengl

I encountered the same problem after modifying the common.py file, and the prediction boxes were all wrong.

Skr20200701 avatar Jul 23 '20 08:07 Skr20200701

yes, i met same problem, i think retrained mode will solve this problem?@sunnyden

panchengl avatar Jul 23 '20 09:07 panchengl

Removing slice does not require retraining the model. However, you should decode the boxes as if you had inputted an image two times larger than the network input size. If you are using the code in this repo without any modification, please reassure that you have generated the onnx model with an input of ~~320x240~~ 320x320.

sunnyden avatar Jul 23 '20 10:07 sunnyden

image Thank you very much for your reply. I modified the resolution in the export code(640x604->320x240). but i met the same phenomenon, Do you mean I need to modify other places?

panchengl avatar Jul 23 '20 11:07 panchengl

image Thank you very much for your reply. I modified the resolution in the export code(640x604->320x240). but i met the same phenomenon, Do you mean I need to modify other places?

Well, I've double-checked my code. The input size in the python export code should be 320x320😂. Sorry for the mistake. Could you try to export the onnx model with an input of 320x320 again?

sunnyden avatar Jul 23 '20 14:07 sunnyden

ok, I will test and reply to you tomorrow morning, thank U

panchengl avatar Jul 23 '20 14:07 panchengl

hello, i change 640x640 -> 320x320, but get the same error, onnx create process like this: image

wrong boxes like this: image

@sunnyden

panchengl avatar Jul 24 '20 03:07 panchengl

Well, that's weird. Did you run onnx-sim to simplify the model after generating the model? Or did you make any modifications to the code?

On Fri, Jul 24, 2020, 11:09 panchengl [email protected] wrote:

hello, i change 640x640 -> 320x320, but get the same error, onnx create process like this: [image: image] https://user-images.githubusercontent.com/56785763/88357416-c2cd1080-cd9d-11ea-895d-a3d8214a3c99.png

wrong boxes like this: [image: image] https://user-images.githubusercontent.com/56785763/88357466-ee4ffb00-cd9d-11ea-8989-42c0bafd2397.png

@sunnyden https://github.com/sunnyden

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sunnyden/YOLOV5_NCNN_Android/issues/3#issuecomment-663327901, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABA7OF2MCUBNXADIUUVBW33R5D3N5ANCNFSM4PFN5SMQ .

sunnyden avatar Jul 24 '20 03:07 sunnyden

ncnn doesn't support step=2 slice operation. and if change the common.py as you mentioned above, the original input 640 * 640 will not be changed to 320 * 320(while with conv(torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1)) is 320*320). I also tested ONNX model, the anchors need to be divided by 2, then the output BBox will be fixed but still not same as pytorch output. Do you have any other solutions to solve the slice operation?

xingshuohan avatar Jul 24 '20 03:07 xingshuohan

我把app/src/main/cpp/Yolov5.cpp中预测框中心点(cx,cy)坐标乘了4倍,(w,h)分别乘以6倍和3.5倍,预测结果貌似凑对了,不知道能不能这样修改。。请指教

image

Skr20200701 avatar Jul 24 '20 03:07 Skr20200701

我把app/src/main/cpp/Yolov5.cpp中预测框中心点(cx,cy)坐标乘了4倍,(w,h)分别乘以6倍和3.5倍,预测结果貌似凑对了,不知道能不能这样修改。。请指教

image

你是只是测试了几张图片吗?我做了类似的操作,有的图像可以,但是有的图像就会有较大的偏差

xingshuohan avatar Jul 24 '20 03:07 xingshuohan

Another solution is replacing the slice operation with convolutions, and you can make the output exactly the same as the python version.

On Fri, Jul 24, 2020, 11:42 kadebudongtan [email protected] wrote:

ncnn doesn't support step=2 slice operation. and if change the common.py as you mentioned above, the original input 640640 will not be changed to 320320(while with conv(torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1)) is 320*320). I also tested ONNX model, the anchors need to be divided by 2, then the output BBox will be fixed but still not same as pytorch output. Do you have any other solutions to solve the slice operation?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sunnyden/YOLOV5_NCNN_Android/issues/3#issuecomment-663333877, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABA7OFYCHGNO7G5R2AK5FLDR5D7KLANCNFSM4PFN5SMQ .

sunnyden avatar Jul 24 '20 03:07 sunnyden

Thanks much, I go try.

xingshuohan avatar Jul 24 '20 03:07 xingshuohan

我把APP/src/Main/cpp/yolov5.cpp中预测框中心点(Cx,Cy)坐标乘了4倍,(w,h)分别乘以6倍和3.5倍,预测结果貌似凑对了,不知道能不能这样修改.请指教 image

你是只是测试了几张图片吗?我做了类似的操作,有的图像可以,但是有的图像就会有较大的偏差

对,我就测试几张,我这个方法是不行,还是的找其他正规方法的

Skr20200701 avatar Jul 24 '20 03:07 Skr20200701

Problem solved. thanks much

xingshuohan avatar Jul 24 '20 09:07 xingshuohan

hey, how do u solve problem, Modify concat to conv, and then retrain the network?@kadebudongtan

panchengl avatar Jul 24 '20 10:07 panchengl

Hello, did you use convolution operation instead of slicing operation to solve this problem? Does this require retraining? @kadebudongtan

Skr20200701 avatar Jul 26 '20 14:07 Skr20200701

Hi, @panchengl @Skr20200701, I tried to use Pooling layer to do the downsampling, you do not need to retrain the model at all. finally, the result is totally same with the Pytorch output. but that is not the perfect solution since It's just that the output of 4 slice operations is exactly same, and each value is same. That's why the Pooling operation works. I really wonder why the input value for each image is totally same? Anyone who can explain that would be grateful.

xingshuohan avatar Jul 27 '20 08:07 xingshuohan

Another solution is replacing the slice operation with convolutions, and you can make the output exactly the same as the python version. On Fri, Jul 24, 2020, 11:42 kadebudongtan @.> wrote: ncnn doesn't support step=2 slice operation. and if change the common.py as you mentioned above, the original input 640640 will not be changed to 320320(while with conv(torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1)) is 320320). I also tested ONNX model, the anchors need to be divided by 2, then the output BBox will be fixed but still not same as pytorch output. Do you have any other solutions to solve the slice operation? — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#3 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABA7OFYCHGNO7G5R2AK5FLDR5D7KLANCNFSM4PFN5SMQ .

Hey, I did it by convolution operation. Have you compared the time consumption of convolution operation and slicing operation?

xingshuohan avatar Aug 02 '20 09:08 xingshuohan

你好,我解决了自己训练的模型,部署时预测框都在左上角不对的问题了。 【1】在导出onnx模型时,common.py删除切片操作还是采用的return self.conv(torch.cat([x,x,x,x], 1))替代。然后export.py导出模型时,输入大小改为训练模型时的一半,如输入大小640时为[320, 320] image

image

【2】预测框不对是因为YoloV5.h文件中,预测层没有根据自己模型指定对,原来的是“394,“375,“output”这3层输出,可以根据Netron查看自己模型的3个预测层修改,我的是“output”,“423”,“442”,然后预测框正确。 image

image

感谢之前各位大佬的回答和分享!

Skr20200701 avatar Aug 03 '20 13:08 Skr20200701

yes, u are right, problem solved, thanks@Skr20200701

panchengl avatar Aug 04 '20 02:08 panchengl

你好,我解决了自己训练的模型,部署时预测框都在左上角不对的问题了。 【1】在导出onnx模型时,common.py删除切片操作还是采用的return self.conv(torch.cat([x,x,x,x], 1))替代。然后export.py导出模型时,输入大小改为训练模型时的一半,如输入大小640时为[320, 320] image

image

【2】预测框不对是因为YoloV5.h文件中,预测层没有根据自己模型指定对,原来的是“394,“375,“output”这3层输出,可以根据Netron查看自己模型的3个预测层修改,我的是“output”,“423”,“442”,然后预测框正确。 image

image

感谢之前各位大佬的回答和分享!

你好,请问你的模型转出来和pytorch差距大么? 我也按照你的方式改变了对应参数,从pytorch到onnx再到ncnn,虽然解决了框都在左上角的问题,但是还是pytorch版结果差距比较大

shengyucaihua avatar Aug 20 '20 10:08 shengyucaihua

May I ask which version of yolov5 you are using? I noticed that your ncnn file has more than 20 MB, but mine is only 10 MB, and there is no check box in the test result.

sabo-gu avatar Aug 24 '20 08:08 sabo-gu

solution hey all, this is my solution, will get the same results with pytorch. @panchengl @Skr20200701 @shengyucaihua

xingshuohan avatar Sep 05 '20 13:09 xingshuohan

solution hey all, this is my solution, will get the same results with pytorch. @panchengl @Skr20200701 @shengyucaihua

return self.conv(torch.cat([x1,x2,x3,x4], 1))

xingshuohan avatar Sep 05 '20 13:09 xingshuohan

hey, thanks your work, i use youer code class Focus to replace oprignal Focus: first phenomenon: model can be run and don`t modify any others. second phenomenon: map was declined. this is my code and

any errors in my code?:

class Focus(nn.Module): def init(self, c1, c2, k=1, s=1, p=None, g=1, act=True): super(Focus, self).init() self.conv = Conv(c1*4, c2, k, s, p, g, act)

def forward(self, x): # x(b,c,w,h) -> y(b,4c,w/2,h/2)
    kernel_1 = [[1.0, 0.0], [0.0, 0.0]]
    kernel_1 = torch.FloatTensor(kernel_1).expand(3, 1, 2, 2)
    weight_1 = torch.nn.Parameter(kernel_1, requires_grad=False).cuda().half()
    x1 = torch.nn.functional.conv2d(x, weight_1, stride=2, padding=0, groups=3)

    kernel_2 = [[0.0, 1.0], [0.0, 0.0]]
    kernel_2 = torch.FloatTensor(kernel_2).expand(3, 1, 2, 2)
    weight_2 = torch.nn.Parameter(kernel_2, requires_grad=False).cuda().half()
    x2 = torch.nn.functional.conv2d(x, weight_2, stride=2, padding=0, groups=3)

    kernel_3 = [[0.0, 0.0], [1.0, 0.0]]
    kernel_3 = torch.FloatTensor(kernel_3).expand(3, 1, 2, 2)
    weight_3 = torch.nn.Parameter(kernel_3, requires_grad=False).cuda().half()
    x3 = torch.nn.functional.conv2d(x, weight_3, stride=2, padding=0, groups=3)

    kernel_4 = [[0.0, 0.0], [0.0, 1.0]]
    kernel_4 = torch.FloatTensor(kernel_4).expand(3, 1, 2, 2)
    weight_4 = torch.nn.Parameter(kernel_4, requires_grad=False).cuda().half()
    x4 = torch.nn.functional.conv2d(x, weight_4, stride=2, padding=0, groups=3)

    return self.conv(torch.cat([x1,x2,x3,x4], 1))

panchengl avatar Sep 06 '20 05:09 panchengl

@kadebudongtan

panchengl avatar Sep 06 '20 05:09 panchengl

solution hey all, this is my solution, will get the same results with pytorch. @panchengl @Skr20200701 @shengyucaihua

hey,in your code "x1 = F.Conv2d(x, weight_1, stride=2, padding=0, groups=3)" ,what's your F mean?

yao-zheng-yi avatar Oct 09 '20 08:10 yao-zheng-yi

solution hey all, this is my solution, will get the same results with pytorch. @panchengl @Skr20200701 @shengyucaihua

hey,in your code "x1 = F.Conv2d(x, weight_1, stride=2, padding=0, groups=3)" ,what's your F mean?

import torch.nn.functional as F

https://pytorch.org/docs/stable/nn.functional.html?highlight=f%20conv2d#torch.nn.functional.conv2d

Single430 avatar Oct 09 '20 08:10 Single430

solution hey all, this is my solution, will get the same results with pytorch. @panchengl @Skr20200701 @shengyucaihua

hey,in your code "x1 = F.Conv2d(x, weight_1, stride=2, padding=0, groups=3)" ,what's your F mean?

import torch.nn.functional as F

https://pytorch.org/docs/stable/nn.functional.html?highlight=f%20conv2d#torch.nn.functional.conv2d

Thanks!

yao-zheng-yi avatar Oct 09 '20 08:10 yao-zheng-yi