资讯详情

[rknpu][yolov5]自训练yolov5模型运行于rv1126npu上(一)训练yolov5模型并转换为onnx模型

1)如果使用原版yolov5s.pt这种模型框架最终跑出来,可以在1126上运行640,不用零拷贝。x640会花150ms~200ms。产品着陆肯定是不可接受的,所以模型需要轻量优化。

2)rknn-toolkit疑似不支持pow层,没有仔细看,一个一个调查,从结果来看有pow层的输出为零。

3)rknpu官方例程切断了最终锚定,并使用软件编写锚定。可能是因为上面2),锚定被切断了。但是为了减少它cpu占用和运行时间不稳定的可能性,我需要在模型中定的可能性。

4)由于需要量化,锚定部分的输出数量级为100,但信心范围为0~1,精度差太大。如果不处理最终输出信心,则为0或1。因此,有必要将锚定集成在那里。

对于坑1,要解决这个问题,要么更换其他较轻的模型,如NanoDet,实测416*416NanoDet能在1126上跑到30~40ms;要么简化yolov5s项目等模型github.com/EASY-EAI/yolov5.更换卷积核,删除切片等操作,简单使用上述项目进行训练,然后导出。整个过程的最终结果是在1126上跑416*416也能跑到35ms左右。但是,EASY-EAI锚定项目也被切断了。我不能接受那些不想写锚定代码的人,所以我想export修改代码。

先使用EASY-EAI的yolov5训练特化的模型,然后他的导出给了三个选项(可同时使用)

--rknn_mode(主要目的是改变很多东西,提高速度。

--ignore_output_permute(在切割锚定的基础上切割最后一层,以适应rknpu例程,但我不需要)

--add_image_preprocess_layer(多加一个输入Transpose层,据说可以提升set实测输入模式的速度似乎确实提高了一点,不知道是不是误差,但他很奇怪,下面详细说明)

因为我需要锚,但是不知道哪行代码控制锚定,从detect.py分析pt文件因该自带锚定,但EASY如果在导出文件中没有找到切割或添加的部分,则只能使用rknn_mode添加内容yolov5本体的export里面。具体操作:

1)把EASY项目的export.py里if opt.rknn_mode != True:的else:内容直接复制到本体export.py的run函数中。运行看看有什么不好,系统找不到什么。

2)然后补充相应的引用,如:import models;补充相应的文件,如:common_rk_plug_in.py放到models内;补充相应的函数,如:common.py里添上SPP;反正运行时缺少什么补什么。

然后说下add_image_preprocess_layer,EASY-EAI说能提升但是,零拷贝通常用于速度,即map系的操作吧?如果打开这个选项,他的输入将从1开始x3x416x416(NCHW)变成1x416x416x3(NHWC),然后在input后面加一层[0, 3, 1, 2]的Transpose。后处理没有变化,但是rknn-toolkit转模时报错,rknn-toolkit可能只接受NCHW即使格式输入模型,config开force_builtin_perm=True也没用。我不明白,也不知道是否有遗漏。

无论如何,如果您想要此操作,您需要更改以下代码onnx:(有脱裤子放屁的感觉)

import onnx import numpy as np  onnx_model = onnx.load("best.onnx") d = onnx_model.graph.input[0].type.tensor_type.shape.dim d[0].dim_value = 1 d[1].dim_value = 3 d[2].dim_value = 416 d[3].dim_value = 416 graph = onnx_model.graph node  = graph.node id = 0  for i in range(len(node)):     if node[i].op_type == 'Transpose':         if node[i].input[0]=='images':             id = i  old_scale_node = node[id] new_perm = onnx.helper.make_attribute("perm", [0,1,2,3]) del node[id].attribute[0] node[id].attribute.extend([new_perm])  onnx.checker.check_model(onnx_model)  onnx_model = onnx.shape_inference.infer_shapes(onnx_model) onnx.checker.check_model(onnx_model)  onnx.save(onnx_model, 'best .onnx')

上面提到,转rknn后,过pow从netron你可以知道这一点pow参数为2,我们可以pow层改成mul层,让输入层乘以自己,主代码示例如下:

for i in range(len(node)):     if node[i].op_type == 'Pow':         if node[i].input[1]=='336':             id = i  old_scale_node = node[id] graph.node.remove(old_scale_node)  new_scale_node = onnx.helper.make_node(     op_type='Mul',     inputs=335,335     outputs=['337'], ) graph.node.insert(id, new_scale_node) onnx.checker.check_model(onnx_model)

上面还提到锚定需要集成,否则信心精度会丢失。操作是直接锚定的最后一个mul层除416外,主要代码示例如下:(338.npy它是锚定层的参数之一,直接从netron下载即可。338只是名字/代码,不同规格的模型标号可能不同,取决于自己的情况)

for i in range(len(node)):     if node[i].op_type == 'Mul':         if node[i].input[1]=='327':             id = i  old_scale_node = node[id] graph.node.remove(old_scale_node)  mul_tensor = onnx.helper.make_tensor('327_',onnx.TensorProto.FLOAT,[1][8/416] graph.initializer.append(mul_tensor) new_scale_node = onnx.helper.make_node(     op_type='Mul',     inputs=['326','327_'],     outputs=['328'], ) graph.node.insert(id, new_scale_node) onnx.checker.check_model(onnx_model)    for i in range(len(node)):     if node[i].op_type == 'Mul':         if node[i].input[1]=='338':             id = i  old_scale_node = node[id] graph.node.remove(old_scale_node)  data=np.load('338.npy') data=data/416  mul_tensor = onnx.helper.make_tensor('338_',onnx.TensorProto.FLOAT,data.shape,data) graph.initializer.append(mul_tensor) new_scale_node = onnx.helper.make_node(     op_type='Mul',     inputs=['337','338_'],     outputs=['339'], ) graph.node.insert(id, new_scale_node) onnx.checker.check_model(onnx_model)

上述两段代码所需的头尾:

import onnx import numpy as np import torch  onnx_model = onnx.load("best.onnx") graph = onnx_model.graph node  = graph.node id = 0  ''' 重复上述两段代码 '''  onnx_model = onnx.shape_inference.infer_shapes(onnx_model) onnx.checker.check_model(onnx_model)  onnx.save(onnx_model, 'out.onnx')

标签: 100rv浮子液体水位传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司