RV1126做OCR<二>

书接上回…

第七步, 把PaddlePaddle的模型, 转成onnx模型, 因为最重要转成rknn, 而onnx是所有转模型的一个中间点.yolo的pt也是要先转onnx再转rknn的.
这一步坑挺多.
首先PaddleOCR有一个专门的工具, 很好用, 叫paddle2onnx, 顾名思义, 直接就能转, 用pip就可以安装.
装好之后

paddle2onnx --model_dir cell_screen_0625_inference --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file first_det_0625.onnx --enable_dev_version True --opset_version 13 --enable_onnx_checker True

你要在刚才转好的推理模型的output目录下面运行这个命令, 第一个参数是你推理模型的文件夹, 然后只需要修改你要保存的的.onnx文件名.

在这里插入图片描述
就是把推理的三个文件, 转成了下面的这个onnx的文件.

然后写一个简单的脚本, 验证一下这个onnx文件有没有问题:

# 导入 ONNX 库
import onnx
# 载入 ONNX 模型
onnx_model = onnx.load("model.onnx")
# 使用 ONNX 库检查 ONNX 模型是否合理
check = onnx.checker.check_model(onnx_model)
# 打印检查结果
print('check: ', check)

输出check none表示正确

你也可以考虑下载这个onnx文件下来用netron.app看看长啥样.

接下来坑就来了, 因为OCR的模型, 它的输入图片大小是不固定的, 而rknn模型必须使用固定的输入图片大小, 所以需要对模型稍作修改, 先从github下载一下Paddle2Onnx的仓库, 然后在仓库外面, 记住是外面(不然会报找不到version模块错误), 运行:

python -m paddle2onnx.optimize --input_model first_det_0625.onnx --output_model static_model_0625.onnx  --input_shape_dict "{'x':[1,3,640,640]}"

意思就是把是first_det_0625.onnx, 从动态输入修改为固定大小输入, 固定为1,3,640,640.
然后你用nettron.app可以看到onnx头部长这样, 之前可能是个?表示动态输入.
在这里插入图片描述
最后一步, 就是在本地的ubuntu环境, 安装rknn-toolkit 1.7.3 ,必须是1.7.3, 方法是在github找到1.7.3的wheel文件压缩包, pip安装wheel, 然后安装requirement.txt, 安装好rknn-toolkit, 具体方法可以看看rk的官方github.
接着把你的rv1126插到ubuntu上, 运行转模型的py脚本(这个脚本是来自上一篇的提到的大佬的博客):

import os
from rknn.api import RKNN
import numpy as np
import onnxruntime as ort

onnx_model = 'model/static_model_0625.onnx' #onnx路径
save_rknn_dir = 'model/static_model_0625.rknn'#rknn保存路径

def norm(img):
    mean = 0.5
    std = 0.5
    img_data = (img.astype(np.float32)/255 - mean) / std
    return img_data

if __name__ == '__main__':

    # Create RKNN object
    rknn = RKNN(verbose=True)

    # image = np.random.randn(1,3,32,448).astype(np.float32)  
    image = np.random.randn(1,3,640,640).astype(np.float32)   
    # image = np.random.randn(640,640,3,1).astype(np.float32)          
    # 创建一个np数组,分别用onnx和rknn推理看转换后的输出差异,检测模型输入是1,3,640,640 ,识别模型输入是1,3,32,448
    onnx_net = ort.InferenceSession(onnx_model)                         # onnx推理

    onnx_infer = onnx_net.run(None, {'x': norm(image)})          # 如果是paddle2onnx转出来的模型输入名字默认是 "x"

    # pre-process config
    print('--> Config model')
    rknn.config(mean_values=[[127.5, 127.5, 127.5]], std_values=[[127.5, 127.5, 127.5]], reorder_channel='2 1 0', target_platform=['rv1126'], batch_size=4,quantized_dtype='asymmetric_quantized-u8')  # 需要输入为RGB#####需要转化一下均值和归一化的值
    # rknn.config(mean_values=[[0.0, 0.0, 0.0]], std_values=[[255, 255, 255]], reorder_channel='2 1 0', target_platform=['rv1126'], batch_size=1)  # 需要输入为RGB
    print('done')

    # model_name = onnx_model[onnx_model.rfind('/') + 1:]
    # Load ONNX model
    print('--> Loading model %s' % onnx_model)
    ret = rknn.load_onnx(model=onnx_model)
    if ret != 0:
        print('Load %s failed!' % onnx_model)
        exit(ret)
    print('done')
    # Build model
    print('--> Building model')
    # rknn.build(do_quantization=False)
    ret = rknn.build(do_quantization=True, dataset='coco_dataset_1.txt', pre_compile=True)
    # do_quantization是否对模型进行量化,datase量化校正数据集,pre_compil模型预编译开关,预编译 RKNN 模型可以减少模型初始化时间,
    # 但是无法通过模拟器进行推理或性能评估
    if ret != 0:
        print('Build net failed!')
        exit(ret)
    print('done')

    # Export RKNN model
    print('--> Export RKNN model')
    ret = rknn.export_rknn(save_rknn_dir)
    if ret != 0:
        print('Export rknn failed!')
        exit(ret)

    ret = rknn.init_runtime(target='rv1126',device_id="a9d00ab1f032c17a")           
     # 两个参数分别是板子型号和device_id,device_id在双头usb线连接后通过 adb devices查看
    if ret != 0:
        print('init runtime failed.')
        exit(ret)
    print('done')

    # Inference
    print('--> Running model')
    outputs = rknn.inference(inputs=[image])

    # perf
    print('--> Begin evaluate model performance')
    perf_results = rknn.eval_perf(inputs=[image])              # 模型评估
    print('done')
    print()

    print("->>模型前向对比!")
    print("--------------rknn outputs--------------------")
    print(outputs[0])
    print()

    print("--------------onnx outputs--------------------")
    print(onnx_infer[0])
    print()

    std = np.std(outputs[0]-onnx_infer[0])
    print(std)                                # 如果这个值比较大的话,说明模型转换后不太理想

    rknn.release()


修改一下输入输出的模型文件的位置, 然后建一个coco_dataset_1.txt文件, 里面放一个图片的文件名

在这里插入图片描述
在这里插入图片描述
用来做量化用, 然后pre_compile用True或者False都可以, 如果用False模型加载大概需要30秒到1分钟.
另外修改一下你1126的adb device_id.

ret = rknn.init_runtime(target='rv1126',device_id="a9d00ab1f032c17a")  

顺利的话, 就会生成一个rknn文件, 放到板子上就可以推理了, 具体推理用的代码, 去我github搜一下即可.

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值