以身份证检测Demo 为例,记录yolox模型部署到前端的过程.
目标
将训练好的yolox模型部署到前端
其中:
- yolox为’MEGVII旷视’发布的开源目标检测模型.
- yolox模型使用官方开源项目YOLOX
训练的来, 原始模型是Pytorch的checkpoint格式, 该项目自带转换脚本
tools/export_onnx.py
可以将模型转为onnx格式发布.
前提
- 训练好的yolox模型(onnx格式).
- 模型转换运行环境:windows10, python3.8, 必要的包, 通过pip安装
1
pip install onnx, onnx_tf, tensorflow, tensorflowjs
- 前端开发环境:windows10, vue3.2.19, vite2, 必要的包, 通过npm安装
1
npm install @tensorflow/tfjs
流程
转换模型
模型转换步骤从导出的onnx格式模型开始, 假设训练好的模型文件路径为C:\YOLOX-main\YOLOX_outputs\onnx\nano.onnx
1 | onnx_filename = r'C:\YOLOX-main\YOLOX_outputs\onnx\nano.onnx' |
从onnx转到tensorflow(SavedModel)
用python执行
1 | import os |
执行后得到对应的模型目录nano.onnx_graph.pb
从tensorflow(SavedModel)转到Tensorflow.js可用的web格式
在命令行执行
1 | tensorflowjs_converter --input_format=tf_saved_model --output_node_names='outputnode' C:\YOLOX-main\YOLOX_outputs\onnx\nano.onnx_graph.pb C:\YOLOX-main\YOLOX_outputs\onnx |
执行后得到两个文件model.json
和group1-shard1of1.bin
, 分别是图和权重数据(注意权重文件不可改名)
参考:tfjs文档
部署到前端
以下前端脚本均基于vue3, script setup
特性
用Tensorflow.js加载模型
加载图
首先将上述的model.json
和group1-shard1of1.bin
复制到vue3项目的public
目录下.
1 | const MODEL_URL = './model.json' |
注意, 这里tf.loadGraphModel 如果是在nginx等生产环境下载入模型文件需要定义http请求头如下
1 | const headers = new Headers() |
使用0数据,测试模型
构建一个全由0组成的输入数据, 来测试模型是否正常工作, 控制台不报错即可(实际上权重的加载也是在第一次调用模型预测时完成的, 所以运行时间会比较长).
1 | const zeros = tf.zeros([1,3,416,416]) |
上述输入数据的shape
是[1,3,416,416]
是由于训练模型时用的时416*416大小的彩色图, 第二维的3表示3个颜色通道, 第0维的1表示batch中只有一张图.
实际输入数据的shape
可能因yolox模型而异
优化加载过程
加载模型的时间相对较长, 为避免页面卡顿, 可以用async使模型加载异步于页面, 完整的加载过程如下
1 | const MODEL_URL = './model.json' |
参考:tfjsAPI文档
模型输入预处理
1 | async function yolox预处理(图片数据, 模型尺寸=[416,416]){ |
参考:yolox源码
模型输出后处理
1 | async function yolox后处理(原始输出, 模型尺寸=[416,416], 缩放=1., 有效分阈值=0.1, 重合比阈值=0.4){ |
后处理过程耗时较多, 原因是处理过程中频繁构建Tensor.
参考:yolox源码
演示
后记
上述yolox模型部署到前端处理一张图片需要2~4秒, 相对的python端onnx模型仅需200毫秒左右. 主要的延迟原因在于后处理过程.
部署小型的目标检测模型用yolo3可能会更好, 识别效果大差不差, 代码还简单不少.