Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修改后的LPRNet代码 #1

Closed
zhongwenkun886 opened this issue Apr 20, 2021 · 16 comments
Closed

修改后的LPRNet代码 #1

zhongwenkun886 opened this issue Apr 20, 2021 · 16 comments

Comments

@zhongwenkun886
Copy link

zhongwenkun886 commented Apr 20, 2021

您好,按 https://github.com/hpc203/license-plate-detect-recoginition-pytorch 重新定义LPRNet,是否需要重新训练模型呢,还是直接加载原模型 Final_LPRNet_model.pth 就可以了?还是要重新训练吧?
谢谢。

@hpc203
Copy link
Owner

hpc203 commented Apr 20, 2021

重新定义LPRNet

您说的“重新定义LPRNet”,是修改原始LPRNet里的哪个模块的结构呢?

@zhongwenkun886
Copy link
Author

重新定义LPRNet

您说的“重新定义LPRNet”,是修改原始LPRNet里的哪个模块的结构呢?

即按你项目 https://github.com/hpc203/license-plate-detect-recoginition-pytorch 里的my_lprnet定义,用它来加载原 https://github.com/sirius-ai/LPRNet_Pytorch 里的训练好的模型,应该是不行吧?
另外,我把您项目 https://github.com/hpc203/license-plate-detect-recoginition-pytorch 里的my_lprnet模型转成onnx时,提示“TracerWarning: Converting a tensor to a Python number might cause the trace to be incorrect. We can't record the data flow of Python values, so this value will be treated as a constant in the future. This means that the trace might not generalize to other inputs!”,看了下转换后的网络结构,它把torch.div里的除数变成一个常数了,而不是动态的去计算特征图的平均数,这估计有问题吧?

@hpc203
Copy link
Owner

hpc203 commented Apr 20, 2021

在我的项目 https://github.com/hpc203/license-plate-detect-recoginition-pytorch 里的my_lprnet定义里,我把池化层用F.max_pool3d的方式做计算的,而在原 https://github.com/sirius-ai/LPRNet_Pytorch 里,它把池化层用nn.MaxPool3d的方式定义在nn.Sequential,用原模型加载到my_lprnet里肯定会出错的。其次,在我的my_lprnet里,你仔细看torch.div里的除数多了一个.item(),为什么要这么做,可以参考我的博文 https://blog.csdn.net/nihate/article/details/115504611
你看torch.div里的除数是上一行代码f = torch.mean(f)得到的,在pytorch对一个4维张量求平均值后得到的是没有形状信息的张量,其实是一个标量数值,如果想要转化成标量数值,那就需要加.item()。这个在深度学习训练程序里,求loss后访问loss数值时,经常会使用到这个

@hpc203
Copy link
Owner

hpc203 commented Apr 20, 2021

在我的项目 https://github.com/hpc203/license-plate-detect-recoginition-pytorch 里的my_lprnet定义里,我把池化层用F.max_pool3d的方式做计算的,而在原 https://github.com/sirius-ai/LPRNet_Pytorch 里,它把池化层用nn.MaxPool3d的方式定义在nn.Sequential,用原模型加载到my_lprnet里肯定会出错的。其次,在我的my_lprnet里,你仔细看torch.div里的除数多了一个.item(),为什么要这么做,可以参考我的博文 https://blog.csdn.net/nihate/article/details/115504611
你看torch.div里的除数是上一行代码f = torch.mean(f)得到的,在pytorch对一个4维张量求平均值后得到的是没有形状信息的张量,其实是一个标量数值,如果想要转化成标量数值,那就需要加.item()。这个在深度学习训练程序里,求loss后访问loss数值时,经常会使用到这个

池化层里没有训练学习的参数,因此我觉得池化层没必要使用nn.MaxPool这种方式定义在__init__构造函数里,直接使用F.max_pool更简洁

@hpc203
Copy link
Owner

hpc203 commented Apr 20, 2021

在我的项目 https://github.com/hpc203/license-plate-detect-recoginition-pytorch 里的my_lprnet定义里,我把池化层用F.max_pool3d的方式做计算的,而在原 https://github.com/sirius-ai/LPRNet_Pytorch 里,它把池化层用nn.MaxPool3d的方式定义在nn.Sequential,用原模型加载到my_lprnet里肯定会出错的。其次,在我的my_lprnet里,你仔细看torch.div里的除数多了一个.item(),为什么要这么做,可以参考我的博文 https://blog.csdn.net/nihate/article/details/115504611
你看torch.div里的除数是上一行代码f = torch.mean(f)得到的,在pytorch对一个4维张量求平均值后得到的是没有形状信息的张量,其实是一个标量数值,如果想要转化成标量数值,那就需要加.item()。这个在深度学习训练程序里,求loss后访问loss数值时,经常会使用到这个

你可以设断点调时运行程序,比较一下out1 = torch.div(out1, f.item())和out1 = torch.div(out1, f)里的除数的区别

@zhongwenkun886
Copy link
Author

zhongwenkun886 commented Apr 21, 2021

非常感谢您的指导,您提到的博文我也看了,对我来说也是很有参考价值的。
现在我还有个疑问,在 torch.div(out1, f.item()) 里,f 加不加.item(),对于原python程序都没有影响,但转换成onnx模型后,就有区别了,见下图(我这里用Netron查看),第一个图是没加.item(),第二个图是加了,加了.item()后,转为onnx模型后,torch.div里的除数就变成一个常数了。
图片

图片

@hpc203
Copy link
Owner

hpc203 commented Apr 21, 2021

非常感谢您的指导,您提到的博文我也看了,对我来说也是很有参考价值的。
现在我还有个疑问,在 torch.div(out1, f.item()) 里,f 加不加.item(),对于原python程序都没有影响,但转换成onnx模型后,就有区别了,见下图(我这里用Netron查看),第一个图是没加.item(),第二个图是加了,加了.item()后,转为onnx模型后,torch.div里的除数就变成一个常数了。
图片

图片

确实,没有加item()的第一幅图里,Div层有两个输入,能够看清楚这两个输入是来自哪两个层的输出的。而加了item(0的第而幅图,Div层只有一个输入,看不出常数B来自哪个层的输出,因为这时的常数B不是一个张量了,没法通过gran_fn追踪到它来自哪一层的输出,这种图不利于理解网络结构。
谢谢你的提醒,我当初之所加.item()是因为我发现没有加.item()的时后转onnx文件,用opencv的深度学习模块加载onnx文件会出错,我没有做Netron读onnx文件生成网络结构图的程序,你做的这个实验可以算是pytorch转onnx时需要注意的一个坑。

@zhongwenkun886
Copy link
Author

我用 onnxruntime 在python上测试了一下转换后onnx模型,没加.item()时,同样的输入数据,和pytorch的输出是一致的,但加了后,就不一致了(因为转换到onnx模型时,把 torch.div()的除数强制转换成一个固定常数吧?)。
那么,前辈,这个问题应该怎么解决呢?我也想把它转到OpenCV上跑。

@hpc203
Copy link
Owner

hpc203 commented Apr 21, 2021

我用 onnxruntime 在python上测试了一下转换后onnx模型,没加.item()时,同样的输入数据,和pytorch的输出是一致的,但加了后,就不一致了(因为转换到onnx模型时,把 torch.div()的除数强制转换成一个固定常数吧?)。
那么,前辈,这个问题应该怎么解决呢?我也想把它转到OpenCV上跑。

你那边在没加.item()时生成的onnx文件,用OpenCV加载这个onnx文件做前向推理,运行程序会报错吗?

@zhongwenkun886
Copy link
Author

我把您项目 https://github.com/hpc203/license-plate-detect-recoginition-pytorch里自带的 my_lprnet_model.pth 模型转换到onnx, 放到这个项目里去跑,在 this->net = readNet 这里程序就崩溃了(不管有没有.item()都奔溃),提示如下:
图片
用这项目里自带的 Final_LPRNet_model.onnx 模型没有奔溃,但识别结果是不对的。用Netron看了下两个模型图, Final_LPRNet_model.onnx是把nn.BatchNorm2d的层都去掉了。至于为什么奔溃,我也不清楚。
我的环境是 win10,pytorch1.6,opencv4.5.2

@hpc203
Copy link
Owner

hpc203 commented Apr 21, 2021

我把您项目 https://github.com/hpc203/license-plate-detect-recoginition-pytorch里自带的 my_lprnet_model.pth 模型转换到onnx, 放到这个项目里去跑,在 this->net = readNet 这里程序就崩溃了(不管有没有.item()都奔溃),提示如下:
图片
用这项目里自带的 Final_LPRNet_model.onnx 模型没有奔溃,但识别结果是不对的。用Netron看了下两个模型图, Final_LPRNet_model.onnx是把nn.BatchNorm2d的层都去掉了。至于为什么奔溃,我也不清楚。
我的环境是 win10,pytorch1.6,opencv4.5.2

看样子是concat层出问题的,https://github.com/hpc203/license-plate-detect-recoginition-pytorch 这套程序跑通了吗?在转换onnx文件时,要把网络里的3维池化层拆分成两个2维池化层

@zhongwenkun886
Copy link
Author

https://github.com/hpc203/license-plate-detect-recoginition-pytorch 这套程序我在python上能跑通,输出结果也正常。就是转成onnx在OpenCV上跑出上述问题。
谢谢

@hpc203
Copy link
Owner

hpc203 commented Apr 21, 2021

https://github.com/hpc203/license-plate-detect-recoginition-pytorch 这套程序我在python上能跑通,输出结果也正常。就是转成onnx在OpenCV上跑出上述问题。
谢谢

这套程序里使用了两个深度学习模型,一个是使用retinaface做车牌检测,另一个是使用LPRNet做车牌识别,在把LPRNet生成onnx文件时,检查一下输入参数,是否跟pyorch版本的一致

@zhongwenkun886
Copy link
Author

我把刚才在OpenCV加载时崩溃的onnx模型(没加.item()的)转成MNN模型,输出的结果和pytorch版一致。
谢谢

@hpc203
Copy link
Owner

hpc203 commented Apr 21, 2021

我把刚才在OpenCV加载时崩溃的onnx模型(没加.item()的)转成MNN模型,输出的结果和pytorch版一致。
谢谢

那从这个实验,可以看出opencv里的深度学习模块对onnx文件的兼容性不如MNN的好

@hpc203
Copy link
Owner

hpc203 commented Apr 21, 2021

我把刚才在OpenCV加载时崩溃的onnx模型(没加.item()的)转成MNN模型,输出的结果和pytorch版一致。
谢谢

那从这个实验,可以看出opencv里的深度学习模块对onnx文件的兼容性不如MNN的好

在pytorch转onnx后,加载onnx文件做前向计算的方式有很多种,比如opencv,onnxruntime等等的,只是我习惯使用opencv,如果加载出错,那可以换一种方式

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants