YOLOv8模型pytorch格式转为onnx格式

一、YOLOv8的Pytorch网络结构

model DetectionModel((model): Sequential((0): Conv((conv): Conv2d(3, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))(act): SiLU(inplace=True))(1): Conv((conv): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))(act): SiLU(inplace=True))(2): C2f((cv1): Conv((conv): Conv2d(128, 128, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(320, 128, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(m): ModuleList((0-2): 3 x Bottleneck((cv1): Conv((conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True)))))(3): Conv((conv): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))(act): SiLU(inplace=True))(4): C2f((cv1): Conv((conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(m): ModuleList((0-5): 6 x Bottleneck((cv1): Conv((conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True)))))(5): Conv((conv): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))(act): SiLU(inplace=True))(6): C2f((cv1): Conv((conv): Conv2d(512, 512, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(m): ModuleList((0-5): 6 x Bottleneck((cv1): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True)))))(7): Conv((conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))(act): SiLU(inplace=True))(8): C2f((cv1): Conv((conv): Conv2d(512, 512, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(1280, 512, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(m): ModuleList((0-2): 3 x Bottleneck((cv1): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True)))))(9): SPPF((cv1): Conv((conv): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(m): MaxPool2d(kernel_size=5, stride=1, padding=2, dilation=1, ceil_mode=False))(10): Upsample(scale_factor=2.0, mode='nearest')(11): Concat()(12): C2f((cv1): Conv((conv): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(1280, 512, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(m): ModuleList((0-2): 3 x Bottleneck((cv1): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True)))))(13): Upsample(scale_factor=2.0, mode='nearest')(14): Concat()(15): C2f((cv1): Conv((conv): Conv2d(768, 256, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(640, 256, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(m): ModuleList((0-2): 3 x Bottleneck((cv1): Conv((conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True)))))(16): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))(act): SiLU(inplace=True))(17): Concat()(18): C2f((cv1): Conv((conv): Conv2d(768, 512, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(1280, 512, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(m): ModuleList((0-2): 3 x Bottleneck((cv1): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True)))))(19): Conv((conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))(act): SiLU(inplace=True))(20): Concat()(21): C2f((cv1): Conv((conv): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(1280, 512, kernel_size=(1, 1), stride=(1, 1))(act): SiLU(inplace=True))(m): ModuleList((0-2): 3 x Bottleneck((cv1): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(cv2): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True)))))(22): PostDetect((cv2): ModuleList((0): Sequential((0): Conv((conv): Conv2d(256, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(1): Conv((conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(2): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1)))(1-2): 2 x Sequential((0): Conv((conv): Conv2d(512, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(1): Conv((conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(2): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1))))(cv3): ModuleList((0): Sequential((0): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(1): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(2): Conv2d(256, 35, kernel_size=(1, 1), stride=(1, 1)))(1-2): 2 x Sequential((0): Conv((conv): Conv2d(512, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(1): Conv((conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(act): SiLU(inplace=True))(2): Conv2d(256, 35, kernel_size=(1, 1), stride=(1, 1))))(dfl): DFL((conv): Conv2d(16, 1, kernel_size=(1, 1), stride=(1, 1), bias=False))))
)

yolov8网络从1-21层与pt文件相对应是BackBone和Neck模块,22层是Head模块。

二、转ONNX步骤

 2.1 yolov8官方

"""
代码解释
pt模型转为onnx格式
"""
import os
from ultralytics import YOLO
model = YOLO("weights/best.pt")
success = model.export(format="onnx")print("导出成功!")

将pytorch转为onnx后,pytorch支持的一系列计算就会转为onnx所支持的算子,若没有相对应的就会使用其他方式进行替换(比如多个计算替换其单个)。比较常见是conv和SiLU合并成一个Conv模块进行。

其中,1*4*8400表示每张图片预测 8400 个候选框,每个框有 4 个参数边界框坐标 (x,y,w,h)。 1*35*8400类同,1和4800代表意义相同,35是类别属性包含了其置信度概率值。

最后两个输出Concat操作,得到1*39*8400。最后根据这个结果去进行后续操作。

2.2 自定义转换

所谓的自定义转换其实是在转onnx时,对1*39*8400多加了一系列自定义操作例如NMS等。

2.2.1 加载权重并优化结构

YOLOv8 = YOLO(args.weights) #替换为自己的权重
model = YOLOv8.model.fuse().eval()

2.2.2 后处理检测模块

def gen_anchors(feats: Tensor,strides: Tensor,grid_cell_offset: float = 0.5) -> Tuple[Tensor, Tensor]:"""生成锚点,并计算每个锚点的步幅。参数:feats (Tensor): 特征图,通常来自不同的网络层。strides (Tensor): 每个特征图的步幅(stride)。grid_cell_offset (float): 网格单元的偏移量,默认为0.5。返回:Tuple[Tensor, Tensor]: 锚点的坐标和对应的步幅张量。"""anchor_points, stride_tensor = [], []assert feats is not None  # 确保输入的特征图不为空dtype, device = feats[0].dtype, feats[0].device  # 获取特征图的数据类型和设备# 遍历每个特征图,计算锚点for i, stride in enumerate(strides):_, _, h, w = feats[i].shape  # 获取特征图的高(h)和宽(w)sx = torch.arange(end=w, device=device,dtype=dtype) + grid_cell_offset  # 计算 x 轴上的锚点位置sy = torch.arange(end=h, device=device,dtype=dtype) + grid_cell_offset  # 计算 y 轴上的锚点位置sy, sx = torch.meshgrid(sy, sx)  # 生成网格坐标anchor_points.append(torch.stack((sx, sy), -1).view(-1, 2))  # 将 x 和 y 组合成坐标点stride_tensor.append(torch.full((h * w, 1), stride, dtype=dtype, device=device))  # 生成步幅张量return torch.cat(anchor_points), torch.cat(stride_tensor)  # 返回合并后的锚点和步幅class customize_NMS(torch.autograd.Function):"""继承torch.autograd.Function用于TensorRT的非极大值抑制(NMS)自定义函数。"""@staticmethoddef forward(ctx: Graph,boxes: Tensor,scores: Tensor,iou_threshold: float = 0.65,score_threshold: float = 0.25,max_output_boxes: int = 100,background_class: int = -1,box_coding: int = 0,plugin_version: str = '1',score_activation: int = 0) -> Tuple[Tensor, Tensor, Tensor, Tensor]:"""正向计算NMS输出,模拟真实的TensorRT NMS过程。参数:boxes (Tensor): 预测的边界框。scores (Tensor): 预测框的置信度分数。其他参数同样为NMS的超参数。返回:Tuple[Tensor, Tensor, Tensor, Tensor]: 包含检测框数量、框坐标、置信度分数和类别标签。"""batch_size, num_boxes, num_classes = scores.shape  # 获取批量大小、框数量和类别数num_dets = torch.randint(0,max_output_boxes, (batch_size, 1),dtype=torch.int32)  # 随机生成检测框数量(仅为模拟)boxes = torch.randn(batch_size, max_output_boxes, 4)  # 随机生成预测框scores = torch.randn(batch_size, max_output_boxes)  # 随机生成分数labels = torch.randint(0,num_classes, (batch_size, max_output_boxes),dtype=torch.int32)  # 随机生成类别标签return num_dets, boxes, scores, labels  # 返回模拟的结果@staticmethoddef symbolic(g,boxes: Value,scores: Value,iou_threshold: float = 0.45,score_threshold: float = 0.25,max_output_boxes: int = 100,background_class: int = -1,box_coding: int = 0,score_activation: int = 0,plugin_version: str = '1') -> Tuple[Value, Value, Value, Value]:"""计算图的符号函数,供TensorRT使用。参数:g: 计算图对象boxes (Value), scores (Value): 传入的边界框和得分其他参数是用于配置NMS的参数。返回:经过NMS处理的检测框、得分、类别标签及检测框数量。"""out = g.op('TRT::EfficientNMS_TRT',boxes,scores,iou_threshold_f=iou_threshold,score_threshold_f=score_threshold,max_output_boxes_i=max_output_boxes,background_class_i=background_class,box_coding_i=box_coding,plugin_version_s=plugin_version,score_activation_i=score_activation,outputs=4)  # 使用TensorRT的EfficientNMS插件nums_dets, boxes, scores, classes = out  # 获取输出的检测框数量、框坐标、得分和类别return nums_dets, boxes, scores, classes  # 返回结果class Post_process_Detect(nn.Module):"""用于后处理的检测模块,执行检测后的非极大值抑制(NMS)。"""export = Trueshape = Nonedynamic = Falseiou_thres = 0.65  # 默认的IoU阈值conf_thres = 0.25  # 默认的置信度阈值topk = 100  # 输出的最大检测框数量def __init__(self, *args, **kwargs):super().__init__()def forward(self, x):"""执行后处理操作,提取预测框、置信度和类别。参数:x (Tensor): 输入的特征图。返回:Tuple[Tensor, Tensor, Tensor]: 预测框、置信度和类别。"""shape = x[0].shape  # 获取输入的形状b, res, b_reg_num = shape[0], [], self.reg_max * 4# b为特征列表第一个元素的批量大小,表示处理的样本数量,# res声明一个空列表存储处理过的特征图# b_reg_num为回归框的数量#遍历特征层(self.nl表示特征层数),将每一层的框预测和分类预测拼接。for i in range(self.nl):res.append(torch.cat((self.cv2[i](x[i]), self.cv3[i](x[i])), 1))  # 特征拼接# 调用# make_anchors# 生成锚点和步幅,用于还原边界框的绝对坐标。if self.dynamic or self.shape != shape:self.anchors, self.strides = (x.transpose(0, 1) for x in gen_anchors(x, self.stride, 0.5))  # 生成锚点和步幅self.shape = shape  # 更新输入的形状x = [i.view(b, self.no, -1) for i in res]  # 调整特征图形状y = torch.cat(x, 2)  # 拼接所有特征图boxes, scores = y[:, :b_reg_num, ...], y[:, b_reg_num:, ...].sigmoid()  # 提取框和分数boxes = boxes.view(b, 4, self.reg_max, -1).permute(0, 1, 3, 2)  # 变换框的形状boxes = boxes.softmax(-1) @ torch.arange(self.reg_max).to(boxes)  # 对框进行softmax处理boxes0, boxes1 = -boxes[:, :2, ...], boxes[:, 2:, ...]  # 分离框的不同部分boxes = self.anchors.repeat(b, 2, 1) + torch.cat([boxes0, boxes1], 1)  # 合并框坐标boxes = boxes * self.strides  # 乘以步幅return customize_NMS.apply(boxes.transpose(1, 2), scores.transpose(1, 2),self.iou_thres, self.conf_thres, self.topk)  # 执行NMSdef optim(module: nn.Module):setattr(module, '__class__', Post_process_Detect)for item in model.modules():optim(item)item.to(args.device) #输入cpu或者gpu的卡号

自定义这里是在yolo官方得到的1*4*8400和1*35*8400进行矩阵转换2<->3,最后引入EfficientNMS_TRT插件后处理,可以有效加速NMS处理。

2.2.3  EfficientNMS_TRT插件

EfficientNMS_TRT 是 TensorRT 中的一个高效非极大值抑制 (NMS) 插件,用于快速过滤检测框。它通过优化的 CUDA 实现来执行 NMS 操作,特别适合于深度学习推理阶段中目标检测任务的后处理。支持在一个批次中对多个图像同时执行 NMS。

输出结果为num_dets, detection_boxes, detection_scores, detection_classes ,分别代表经过 NMS 筛选后保留的边界框数,每张图片保留的检测框的坐标,每张图片中保留下来的检测框的分数(由高到低),每个保留下来的边界框的类别索引。

三、结语 

仅供学习使用!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/62641.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论文解读:Reward criteria impact on the performance ofreinforcement learning...

Reward criteria impact on the performance ofreinforcement learning agent for autonomous navigation 译文&#xff1a; 奖励准则对自主导航强化学习agent性能的影响 摘要&#xff1a; 在强化学习中&#xff0c;主体在环境中的每个时间步采取行动&#xff08;遵循策略&…

glog在vs2022 hello world中使用

准备工作 设置dns为阿里云dns 223.5.5.5&#xff0c;下载cmake&#xff0c;vs2022&#xff0c;git git clone https://github.com/google/glog.git cd glog mkdir build cd build cmake .. 拷贝文件 新建hello world并设置 设置预处理器增加GLOG_USE_GLOG_EXPORT;GLOG_NO_AB…

速盾:介绍一下高防cdn的缓存响应事什么功能?

高防CDN&#xff08;Content Delivery Network&#xff09;是一种基于分布式缓存技术的网络加速服务&#xff0c;能够提供强大的缓存响应功能。它的缓存响应功能主要包括缓存加速和智能缓存两个方面。 首先&#xff0c;高防CDN的缓存加速功能是指通过在全球范围内部署大量的缓…

搜索二维矩阵 II(java)

题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 代码思路&#xff1a; 用暴力算法&#xff1a; class Solution {public boolean searchMatrix(…

基于vite创建的react18项目的单元测试

题外话 最近一个小伙伴进了字节外包&#xff0c;第一个活就是让他写一个单元测试。 嗯&#xff0c;说实话&#xff0c;在今天之前我只知道一些理论&#xff0c;但是并没有实操过&#xff0c;于是我就试验了一下。 通过查询资料&#xff0c;大拿们基本都说基于vite的项目&…

两个生活中的例子反向理解正/反向代理?

正向代理 场景&#xff1a;你在学校里想访问一个被限制的网站&#xff0c;比如某个社交媒体平台。 操作方式&#xff1a; 你把访问请求发送给学校的代理服务器&#xff08;正向代理&#xff09;。代理服务器代表你向互联网发出请求&#xff0c;去访问那个受限的网站。网站的响…

GY302光照传感器模块详解

目录 一、引言 二、功能特点 三、工作原理 四、引脚功能 五、应用场景 六、使用方法 七、总结 一、引言 在当今科技飞速发展的时代&#xff0c;传感器技术在各个领域都发挥着至关重要的作用。光照传感器作为一种能够感知环境光照强度的设备&#xff0c;广泛应用于农业、…

pip install causal-conv1d==1.1.1报错

Building wheels for collected packages: causal-conv1d Building wheel for causal-conv1d (setup.py) ... error error: subprocess-exited-with-error python setup.py bdist_wheel did not run successfully. │ exit code: 1 ╰─> [8 lines of output]…

【WRF后处理】WRF模拟效果评价及可视化:MB、RMSE、IOA、R

【WRF后处理】模拟效果评价及可视化 准备工作模型评价指标Python实现代码Python处理代码:导入站点及WRF模拟结果可视化图形及评价指标参考在气象和环境建模中(如使用 WRF 模型进行模拟),模型性能评价指标是用于定量评估模拟值与观测值之间偏差和拟合程度的重要工具。 本博客…

facebook欧洲户开户条件有哪些又有何优势?

在当今数字营销时代&#xff0c;Facebook广告已成为企业推广产品和服务的重要渠道。而为了更好地利用这一平台&#xff0c;广告主们需要理解不同类型的Facebook广告账户。Facebook广告账户根据其属性可分为多种类型&#xff0c;包括个人广告账户、企业管理&#xff08;BM&#…

Scala学习记录,全文单词统计

package test32 import java.io.PrintWriter import scala.io.Source //知识点 // 字符串.split("分隔符"&#xff1a;把字符串用指定的分隔符&#xff0c;拆分成多个部分&#xff0c;保存在数组中) object test {def main(args: Array[String]): Unit {//从文件1.t…

androidstudio 最新继承 proto kts 方式

在Android Studio中&#xff0c;如果你使用的是Kotlin DSL&#xff08;.kts文件&#xff09;来配置你的Gradle项目&#xff0c;并且你想集成Protocol Buffers&#xff08;Proto&#xff09;&#xff0c;你需要稍微调整你的配置方式。以下是如何在Kotlin DSL中配置Proto集成的步…

FreeRTOS综合代码实例---多级菜单的设计

本文介绍一套基于FreeRTOS的综合代码实例&#xff0c;目标是通过模块化的编程方式实现对多种硬件功能的管理。该实例沿用《FreeRTOS综合代码实例-OLED版本》的框架&#xff0c;重点改进为TFT LCD显示&#xff0c;同时保留了多级菜单的实现。项目链接&#xff1a;FreeRTOS综合代…

ESLint 配置文件全解析:格式、层叠与扩展(3)

配置文件系统处于一个更新期&#xff0c;存在两套配置文件系统&#xff0c;旧的配置文件系统适用于 v9.0.0 之前的版本&#xff0c;而新的配置文件系统适用于 v9.0.0之后的版本&#xff0c;但是目前还处于 v8.x.x 的大版本。 配置文件格式 在 ESLint 中&#xff0c;支持如下格…

终端环境下关闭显示器

终端环境下关闭显示器 使用vbetool vbetool 使用 lrmi 来运行视频 BIOS 中的代码。目前&#xff0c;它能够更改 DPMS 状态、保存/恢复视频卡状态并尝试从头开始初始化视频卡。 vbetool dpms off

OpenMP出现Stack Overflow及其疑问

今天对着《OpenMP核心技术指南》练习OpenMP&#xff0c;其中一个案例: #include <stdio.h> #include <math.h> #include <omp.h>#define ITER 100000000void main() {int i;double A[ITER];for (i 0; i < ITER; i)A[i] 2.0 * i;#pragma omp parallel{/…

Python 视频合并工具

Python 视频合并工具 1.简介&#xff1a; 这是一个使用 moviepy 和 tkinter 创建的简单图形用户界面&#xff08;GUI&#xff09;应用程序&#xff0c;用于合并两个视频文件&#xff0c;并在两个视频之间添加淡入淡出过渡效果。程序的功能是&#xff1a; 选择两个视频&#…

Web开发基础学习——HTTP的理解

Web开发基础学习系列文章目录 第一章 基础知识学习之HTTP的理解 文章目录 Web开发基础学习系列文章目录前言一、HTTP 请求方法二、HTTP 状态码三、HTTP 报文四、示例总结 前言 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是用于在 W…

PYNQ 框架 - 时钟系统 + pl_clk 时钟输出不准确问题

目录 1. 简介 2. PS 时钟计算 2.1 计算框架 2.2 KV260 的参考时钟 2.3 PL_CLK 设置 3. 测试 3.1 Block design 3.2 引脚绑定 3.3 使用 AD2 测量 3.4 调整分频 4. PYNQ 时钟驱动 4.1 源码解析 4.2 查看 PL_CLK 4.3 配置 PL_CLK 5. 总结 1. 简介 ZYNQ MPSoC 具有…

【python量化教程】如何使用必盈API的股票接口,获取最新实时交易数据

实时交易数据简介 股票实时交易数据涵盖股票价格、成交量、涨跌幅等多类信息。其在股票交易中极为关键&#xff0c;高速准确的数据对各方意义重大。投资者可借此及时捕捉机会、优化策略与降低风险&#xff1b;实时准确的实时交易数据是股票市场有效运转的核心要素之一。 使用…