【ORT部署】对bubbliiiing的yolo系列进行进行onnxruntime推理部署

简介: 【ORT部署】对bubbliiiing的yolo系列进行进行onnxruntime推理部署

前言

  当今深度学习技术已经成为人工智能领域的核心技术之一,越来越多的企业和研究机构开始将其应用到实际业务中。但是,要将深度学习模型应用到实际业务中,需要先将其转换为可部署的模型并进行推理部署。这个过程需要考虑到多个方面,例如模型的性能、效率、精度等。ONNX Runtime是一种跨平台的深度学习推理引擎,可以帮助用户快速地将深度学习模型部署到各种不同的硬件设备上,并实现高效、高性能的推理。

  在本文中我将为大家介绍如何使用onnxruntime替代opencv.dnn模块中的net.forward,并综合比对二者推理的差异。

注: 本实验代码以及源码是从使用python&C++对bubbliiiing的yolo系列进行opencv.dnn进行推理部署中变换而来,如大家需要更加详细的代码的话,可以点击连接或者在文末进行评论告知。

ORT推理

  在使用onnxruntime推理部署(后续简称ORT推理部署)之前,应当了解其大体流程:

  1. 准备模型:使用支持ONNX格式的机器学习框架(如PyTorch、TensorFlow等)训练或导出一个ONNX格式的模型。
  2. 加载模型:使用ONNX Runtime提供的API将ONNX格式的模型加载到内存中。
  3. 创建会话:使用ONNX Runtime提供的API创建一个会话对象,用于执行推理任务。
  4. 配置会话:根据需要配置会话,包括硬件加速、运行优化等。
  5. 输入数据:将输入数据传递给会话。
  6. 执行推理:使用会话对象的API执行推理任务。
  7. 输出结果:从会话对象中获取推理结果。

  我们通过上篇文章我们已经知道了第一步准备模型阶段以及根据网络的输出进行解码的部分,因此在本文中我们将重点放在加载模型、创建会话、配置会话、输出数据和执行推理。

读取网络

  查看官网例子,我们容易得到,使用ort读取onnx的方式如下:

scss

复制代码

def readModel(netPath):
    net = ort.InferenceSession(netPath, providers=ort.get_available_providers())
    return net

数据预处理阶段

  在输入数据方面我们仍然是沿用了opencv.dnn模块的blobFromImage函数进行输入图像的处理,这样保证了可以在让网络正常输出图像数据。

ini

复制代码

blob = cv2.dnn.blobFromImage(netInputImg, scalefactor=1 / 255.0, size=(netWidth, netHeight), mean=[104, 117, 123], swapRB=True, crop=False)

网络推理阶段

  在读取了onnx权重文件后我们需要进行ort推理了,我们需要知道在转onnx权重文件时的输入和输出名字(这两个可以通过代码获取,在这里我省去便于快速执行),将数据转为float32的格式

ini

复制代码

input_name = "images"
output_name = "output"
netOutputImg = net.run([output_name], {input_name: blob.astype(np.float32)})

  在后续的解码部分和上篇文章中保持一致。这里就不过多的介绍了。

ORT推理输出结果&DNN推理输出结果

ORT

image.png

DNN

image.png

综合比对DNN与ORT推理

  OpenCV和ONNX Runtime都是流行的深度学习推理框架,它们都支持跨平台的模型部署。下面是它们之间的一些比较:

模型支持:

  OpenCV DNN支持许多深度学习框架的模型,例如Caffe、TensorFlow、Darknet、PyTorch等。但是,它不支持ONNX格式的模型。ONNX Runtime是专门为ONNX模型设计的,因此它支持ONNX格式的模型,但是它也可以加载和运行其他框架的模型。不过需要将其他框架的模型转换为ONNX格式。

模型转换

  OpenCV DNN提供了一些工具和API,可以将各种深度学习框架的模型转换为OpenCV可用的格式,以便在OpenCV中进行推理。ONNX Runtime本身不提供模型转换的功能,但是有许多第三方工具可以将其他框架的模型转换为ONNX格式,例如ONNX官方提供的ONNX Converter。

性能

  在相同硬件和模型条件下,ONNX Runtime通常比OpenCV DNN更快。这是因为ONNX Runtime使用了更先进的推理优化技术,例如TensorRT、OpenVINO等,可以在各种硬件平台上获得更好的性能。

API和易用性

  OpenCV DNN的API相对简单,易于学习和使用。而ONNX Runtime的API更为复杂,需要一些深度学习和编程知识才能使用。

  总体来说,OpenCV DNN和ONNX Runtime都是优秀的深度学习推理框架,可以满足不同的部署需求。如果您的模型已经是ONNX格式的,推荐使用ONNX Runtime进行部署。

结论与吐槽:

  不管是在CPU端或是在GPU端,对于在深度学习有一定基础的同学们来说,在选择推理部署框架的时候,一律选择ORT推理部署框架作为首选!

代码:

ini

复制代码

import random
import time
from math import exp, pow
import cv2
import numpy as np
import onnxruntime as ort
className = ["1", "2", "3", "4"]
# 替换对应yolo的Anchors值
netAnchors = np.asarray([[10.0, 13.0, 16.0, 30.0, 33.0, 23.0],
                         [30.0, 61.0, 62.0, 45.0, 59.0, 119.0],
                         [116.0, 90.0, 156.0, 198.0, 373.0, 326.0]], dtype=np.float32)
netStride = np.asarray([8.0, 16.0, 32.0], dtype=np.float32)
netWidth = 512
netHeight = 512
nmsThreshold = 0.80
boxThreshold = 0.80
classThreshold = 0.80
def GetColors(color_num):
    ColorList = []
    for num in range(color_num):
        R = random.randint(0, 255)
        G = random.randint(0, 255)
        B = random.randint(0, 255)
        BGR = (B, G, R)
        ColorList.append(BGR)
    return ColorList
def Sigmoid(x):
    # x = float(x)
    # out = max(x, 0)
    out = (float(1.) / (float(1.) + exp(-x)))
    return out
def readModel(netPath):
    net = ort.InferenceSession(netPath, providers=ort.get_available_providers())
    return net
def Detect(SrcImg, net, netWidth, netHeight):
    netInputImg = SrcImg
    blob = cv2.dnn.blobFromImage(netInputImg, scalefactor=1 / 255.0, size=(netWidth, netHeight), mean=[104, 117, 123],
                                 swapRB=True, crop=False)
    input_name = "images"
    output_name = "output"
    netOutputImg = net.run([output_name], {input_name: blob.astype(np.float32)})
    ratio_h = float(netInputImg.shape[1] / netHeight)
    ratio_w = float(netInputImg.shape[0] / netWidth)
    pdata = netOutputImg[0]
    classIds = []  # 定义结果线性表
    confidences = []  # 定义置信度线性表
    boxes = []  # 定义坐标线性表
    count = 0
    for stride in range(3):  # netStride = {8.0, 16.0, 32.0} = 3
        grid_x = netWidth / netStride[stride]
        grid_y = netHeight / netStride[stride]
        grid_x, grid_y = int(grid_x), int(grid_y)  # 系统默认是float32,这里是为了下面的循环转为int
        for anchor in range(3):  # netAnchors 的层数 = 3
            anchor_w = netAnchors[stride][anchor * 2]
            anchor_h = netAnchors[stride][anchor * 2 + 1]
            anchor_w, anchor_h = float(anchor_w), float(anchor_h)
            for i in range(grid_x):
                for j in range(grid_y):  
                    pdatabox = pdata[0][count][4]
                    box_score = Sigmoid(pdatabox)  # 获取每一行的box框中含有某个物体的概率
                    if box_score > boxThreshold:  # box的阈值起作用了
                        scores = pdata[0][count][5:]  # 这里的scores理应是一个多维矩阵
                        _, max_class_socre, _, classIdPoint = cv2.minMaxLoc(scores)  # 求最大值以及最大值的位置&位置是元组
                        max_class_socre = np.asarray(max_class_socre, dtype=np.float64)
                        max_class_socre = Sigmoid(max_class_socre)
                        if max_class_socre > classThreshold:  # 类别的置信度起作用
                            # rect[x,y,w,h]
                            pdatax = pdata[0][count][0]
                            x = (Sigmoid(pdatax) * float(2.) - float(0.5) + j) * netStride[stride]  # x
                            pdatay = np.asarray(pdata[0][count][1], dtype=np.float64)
                            y = (Sigmoid(pdatay) * float(2.) - float(0.5) + i) * netStride[stride]  # y
                            pdataw = pdata[0][count][2]
                            w = pow(Sigmoid(pdataw) * float(2.), float(2.0)) * anchor_w  # w
                            pdatah = pdata[0][count][3]
                            h = pow(Sigmoid(pdatah) * float(2.), float(2.0)) * anchor_h  # h
                            left = (x - 0.5 * w) * ratio_w
                            top = (y - 0.5 * h) * ratio_h
                            left, top, W, H = int(left), int(top), int(w * ratio_w), int(h * ratio_h)
                            # 对classIds & confidences & boxes
                            classIds.append(classIdPoint[1])  # 获取最大值的位置
                            confidences.append(max_class_socre * box_score)
                            boxes.append((left, top, W, H))
                    count += 1
    # cv2.dnn.NMSBoxes的bboxes框应该是左上角坐标(x,y)和 w,h, 那么针对不同模型的,要具体情况转化一下,才能应用该函数。
    nms_result = cv2.dnn.NMSBoxes(boxes, confidences, classThreshold, nmsThreshold)  # 抑制处理 返回的是一个数组
    if len(nms_result) == 0:
        return
    else:
        for idx in nms_result:
            classIdx = classIds[idx]
            confidenceIdx = confidences[idx]
            boxsIdx = boxes[idx]
            pt1 = (boxsIdx[0], boxsIdx[1])
            pt2 = (boxsIdx[0] + boxsIdx[2], boxsIdx[1] + boxsIdx[3])
            # 绘制图像目标位置
            # x1, y1, x2, y2 = box[0], box[1], box[0] + box[2], box[1] + box[3]
            cv2.rectangle(SrcImg, pt1, pt2, classIdx, 2, 2)
            cv2.rectangle(SrcImg, (boxsIdx[0], boxsIdx[1] - 18), (boxsIdx[0] + boxsIdx[2], boxsIdx[1]), (255, 0, 255),
                          -1)
            label = "%s:%s" % (className[classIdx], confidenceIdx)  # 给目标进行添加类别名称以及置信度
            FONT_FACE = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(SrcImg, label, (boxsIdx[0] - 2, boxsIdx[1] - 5), FONT_FACE, 0.5, (0, 0, 0), 1)



相关文章
|
3天前
|
监控 计算机视觉 知识图谱
YOLOv10的改进、部署和微调训练总结
YOLOv10在实时目标检测中提升性能与效率,通过无NMS训练解决延迟问题,采用一致的双任务和效率-精度驱动的模型设计。YOLOv10-S比RT-DETR-R18快1.8倍,YOLOv10-B比YOLOv9-C延迟减少46%。新方法包括一致性双标签分配,优化计算冗余和增强模型能力。实验结果显示YOLOv10在AP和延迟上均有显著改善。文章还提供了部署和微调YOLOv10的示例代码。
16 2
|
20天前
|
缓存 Kubernetes 异构计算
使用TensorRT-LLM进行生产环境的部署指南
TensorRT-LLM是一个由Nvidia设计的开源框架,用于在生产环境中提高大型语言模型的性能。该框架是基于 TensorRT 深度学习编译框架来构建、编译并执行计算图,并借鉴了许多 FastTransformer 中高效的 Kernels 实现,并且可以利用 NCCL 完成设备之间的通讯。
254 12
|
20天前
|
编解码 缓存 计算机视觉
改进的yolov5目标检测-yolov5替换骨干网络-yolo剪枝(TensorRT及NCNN部署)-1
改进的yolov5目标检测-yolov5替换骨干网络-yolo剪枝(TensorRT及NCNN部署)-1
160 0
|
20天前
|
人工智能 算法 开发工具
Mixtral 8X7B MoE模型在阿里云PAI平台的微调部署实践
Mixtral 8x7B 是Mixtral AI最新发布的大语言模型,是当前最为先进的开源大语言模型之一。阿里云人工智能平台PAI,提供了对于 Mixtral 8x7B 模型的全面支持,开发者和企业用户可以基于 PAI-快速开始轻松完成Mixtral 8x7B 模型的微调和部署。
|
8月前
|
PyTorch 测试技术 API
Pytorch模型训练与在线部署
本文以CIFAR10数据集为例,通过自定义神经元网络,完成模型的训练,并通过Flask完成模型的在线部署与调用,考略到实际生产模型高并发调用的述求,使用service_streamer提升模型在线并发能力。
581 1
|
20天前
|
算法 PyTorch 计算机视觉
改进的yolov5目标检测-yolov5替换骨干网络-yolo剪枝(TensorRT及NCNN部署)-2
改进的yolov5目标检测-yolov5替换骨干网络-yolo剪枝(TensorRT及NCNN部署)-2
119 1
改进的yolov5目标检测-yolov5替换骨干网络-yolo剪枝(TensorRT及NCNN部署)-2
|
20天前
|
物联网 Shell Swift
NPU推理&微调大模型实战
本文为魔搭社区轻量级训练推理工具SWIFT微调实战教程系列
|
13天前
|
存储 自动驾驶 开发工具
在进行YOLOv3模型部署时,如何评估和选择最适合的硬件平台?
在进行YOLOv3模型部署时,如何评估和选择最适合的硬件平台?
|
20天前
|
并行计算 计算机视觉
YOLOv8太卷啦 | YOLOv8官方仓库正式支持RT-DETR训练、测试以及推理
YOLOv8太卷啦 | YOLOv8官方仓库正式支持RT-DETR训练、测试以及推理
166 0
|
9月前
|
人工智能 物联网 Linux
使用aidlux进行模型迁移、部署、推理
使用aidlux进行模型迁移、部署、推理

热门文章

最新文章