• 瑞芯微RKNN开发·yolov5


    官方预训练模型转换

    1. 下载yolov5-v6.0分支源码解压到本地,并配置基础运行环境。
    2. 下载官方预训练模型
    1. 进入yolov5-6.0目录下,新建文件夹weights,并将步骤2中下载的权重文件放进去。
    2. 修改models/yolo.py文件
        def forward(self, x):
            z = []  # inference output
            for i in range(self.nl):
                x[i] = self.m[i](x[i]).sigmoid()  # conv
            #     bs, _, ny, nx = x[i].shape  # x(bs,255,20,20) to x(bs,3,20,20,85)
            #     x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
    
            #     if not self.training:  # inference
            #         if self.grid[i].shape[2:4] != x[i].shape[2:4] or self.onnx_dynamic:
            #             self.grid[i], self.anchor_grid[i] = self._make_grid(nx, ny, i)
    
            #         y = x[i].sigmoid()
            #         if self.inplace:
            #             y[..., 0:2] = (y[..., 0:2] * 2. - 0.5 + self.grid[i]) * self.stride[i]  # xy
            #             y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # wh
            #         else:  # for YOLOv5 on AWS Inferentia https://github.com/ultralytics/yolov5/pull/2953
            #             xy = (y[..., 0:2] * 2. - 0.5 + self.grid[i]) * self.stride[i]  # xy
            #             wh = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # wh
            #             y = torch.cat((xy, wh, y[..., 4:]), -1)
            #         z.append(y.view(bs, -1, self.no))
    
            # return x if self.training else (torch.cat(z, 1), x)
            return x[0], x[1], x[2]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    1. 新建export_rknn.py文件
    import os
    import torch
    import onnx
    from onnxsim import simplify
    import onnxoptimizer
    import argparse
    from models.yolo import Detect, Model
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser()
        parser.add_argument('--weights', type=str, default='./weights/yolov5n.pt', help='initial weights path') 
    
        #================================================================
        opt = parser.parse_args()
        print(opt)
    
        #Save Only weights
        ckpt = torch.load(opt.weights, map_location=torch.device('cpu'))
        torch.save(ckpt['model'].state_dict(), opt.weights.replace(".pt", "-model.pt"))
    
        #Load model without postprocessing
        new_model = Model("./models/{}.yaml".format(os.path.basename(opt.weights).strip(".pt")))
        new_model.load_state_dict(torch.load(opt.weights.replace(".pt", "-model.pt"), map_location=torch.device('cpu')), False)
        new_model.eval()
    
        #save to JIT script
        example = torch.rand(1, 3, 640, 640)
        traced_script_module = torch.jit.trace(new_model, example)
        traced_script_module.save(opt.weights.replace(".pt", "-jit.pt"))
    
        #save to onnx
        f = opt.weights.replace(".pt", ".onnx")
        torch.onnx.export(new_model, example, f, verbose=False, opset_version=12,
                                training=torch.onnx.TrainingMode.EVAL,
                                do_constant_folding=True,
                                input_names=['data'],
                                output_names=['out0','out1','out2'])
    
        #onnxsim
        model_simp, check = simplify(f)
        assert check, "Simplified ONNX model could not be validated"
        onnx.save(model_simp, opt.weights.replace(".pt", "-sim.onnx"))
    
        #optimize onnx
        passes = ["extract_constant_to_initializer", "eliminate_unused_initializer"]
        optimized_model = onnxoptimizer.optimize(model_simp, passes)
        onnx.checker.check_model(optimized_model)
        onnx.save(optimized_model, opt.weights.replace(".pt", "-op.onnx"))
        print('finished exporting onnx')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    1. 命令行执行python3 export_rknn.py脚本(默认为yolov5n.pt, 加–weights参数可指定权重),转换成功会输出一下信息, 转换后的模型存于权重同级目录(*-op.onnx后缀模型)
    Namespace(weights='./weights/yolov5n.pt')
    finished exporting onnx
    
    • 1
    • 2

    请添加图片描述

    RKNN开发板植入-模型转换篇

    前期准备
    • RKNN开发环境(python)
    • rknn-toolkits2
    详细流程
    1. 进入rknn-toolkits2/examples/onnx/yolov5示例目录下
    2. 修改test.py内容(按需修改ONNX_MODEL、RKNN_MODEL、IMG_PATH、DATASET等等超参数)
    def sigmoid(x):
        # return 1 / (1 + np.exp(-x))
        return x
    
    • 1
    • 2
    • 3
    1. 命令行执行python3 test.py即可获取推理结果
      请添加图片描述

    请添加图片描述

    RKNN开发板植入-NPU加载推理篇(C++)

    后续放出代码

  • 相关阅读:
    【Java】使用stream()串行和并行流,代替for循环一行写完
    ERROR 1366 (HY000): Incorrect string value,mysql插入数据报错?安排
    LVGL移植
    深度剖析React懒加载原理
    某CCC-BASE的逆向
    开发那些事儿:如何利用Go单例模式保障流媒体高并发的安全性?
    网络安全(黑客)自学
    Docker 容器相关的常见面试问题及答案
    使用VirtualBox和Vagrant安装centos7
    C++ 内联和嵌套命名空间
  • 原文地址:https://blog.csdn.net/weixin_41933970/article/details/133879340