当前位置: 首页 > news >正文

jetson Orin nx + yolov8 TensorRT 加速量化 环境配置

参考【Jetson】Jetson Orin NX纯系统配置环境-CSDN博客 

一 系统环境配置:

1.更换源:

sudo vi /etc/apt/sources.list.d/nvidia-l4t-apt-source.list

2.更新源:

sudo apt upgrade
sudo apt update
sudo apt dist-upgrade
sudo apt-get update --fix-missing
sudo reboot

3.安装jetpack

sudo apt install nvidia-jetpack

4.安装jtop 

sudo apt install python3-pip
sudo -H pip3 install -U pip
sudo -H pip install jetson-stats

 jtop查看:

sudo jtop

5.安装超级终端 terminator

sudo apt-get install terminator -y

6.配置CUDA和CUDNN

(1)配置环境变量:

gedit ~/.bashrc

添加以下内容: 

export LD_LIBRARY_PATH=/usr/local/cuda/lib64
export PATH=/usr/local/cuda/bin:$PATH
export CUDA_HOME=/usr/local/cuda

(2)更新环境变量

source ~/.bashrc

(3)复制文件到cuda目录

cd /usr/include && sudo cp cudnn* /usr/local/cuda/include
cd /usr/lib/aarch64-linux-gnu && sudo cp libcudnn* /usr/local/cuda/lib64

(4)查看cuda

nvcc -V

(5)修改文件权限

sudo chmod 777 /usr/local/cuda/include/cudnn.h 
sudo chmod 777 /usr/local/cuda/lib64/libcudnn*

(6)重新软链接

#这里的8.6.0和8对应安装的cudnn版本号和首数字
cd /usr/local/cuda/lib64sudo ln -sf libcudnn.so.8.6.0 libcudnn.so.8sudo ln -sf libcudnn_ops_train.so.8.6.0 libcudnn_ops_train.so.8
sudo ln -sf libcudnn_ops_infer.so.8.6.0 libcudnn_ops_infer.so.8sudo ln -sf libcudnn_adv_train.so.8.6.0 libcudnn_adv_train.so.8
sudo ln -sf libcudnn_adv_infer.so.8.6.0 libcudnn_adv_infer.so.8sudo ln -sf libcudnn_cnn_train.so.8.6.0 libcudnn_cnn_train.so.8
sudo ln -sf libcudnn_cnn_infer.so.8.6.0 libcudnn_cnn_infer.so.8sudo ldconfig

(7)查看cudnn

dpkg -l libcudnn8

二.安装pytorch、torchvision

1、安装pytorch

下载文档根据下载文档选择jetpack对应的pytorch版本,我的jetpack是5.1.3,下载pytorch2.0

下载地址  下载python3.8 对应的pytorch2.0的whl文件    到home目录下

安装依赖环境 

sudo apt-get install libhdf5-serial-dev hdf5-tools libhdf5-dev zlib1g-dev zip libjpeg8-dev
sudo apt-get install liblapack-dev libblas-dev gfortransudo apt-get install libopenblas-base libopenmpi-dev
sudo pip3 install mpi4py
sudo pip3 install Cython

安装pytorch

pip install torch-2.0.0+nv23.05-cp38-cp38-linux_aarch64.whl

 2、安装torchvision

torchvision  自己下对应版本 或者gitclone

torch2.0.0对应torchvision0.15.1

git clone --branch  v0.15.1 https://github.com/pytorch/vision torchvision
export BUILD_VERSION=0.15.1

 进入torchvision文件夹编译

cd torchvision
python3 setup.py install --user

  验证:

import torch
import torchvision
import tensorrt as trttorch.cuda.is_available()		# 检查cuda是否可用
torch.version.cuda				# 查看Pytorch运行时使用的cuda版本
torch.backends.cudnn.enabled	# 查看cudnn是否可用
torch.backends.cudnn.version()  # 查看cudnn版本
print(trt.__version__)
print(torchvision._version_)
# '/usr/local/cuda'pip3 show tensorrt		# 查看tensorrt版本
import torch
torch.__version__
torch.cuda.is_available()
torch.cuda.current_device()
torch.cuda.get_device_name()
python
import torch
import torchvision
print(torch.cuda.is_available())	# 这一步如果输出True那么就成功了!
quit()	# 最后退出python编译

三:安装anaconda 

下载镜像Index of /

Anaconda3-2024.02-1-Linux-aarch64.sh

chmod +x Anaconda3-2024.2-1-Linux-aarch64.sh ./Anaconda3-2024.2-1-Linux-aarch64.sh

yes

四:安装vscode

下载vscode1.85.2

https://update.code.visualstudio.com/1.85.2/linux-deb-arm64/stable

 安装:

sudo dpkg -i code_1.85.2-1705560689_arm64.deb

  打开文件夹:  code .

五.配置yolov8环境

conda create -n yolov8 python=3.8

pip install ultralytics

六.安装ros

Jetson Orin NX 开发指南(3): 安装 ROS 系统_jetson orin nano是ros吗-CSDN博客

七.安装mavros

sudo apt-get install ros-noetic-mavros ros-noetic-mavros-extras
wget https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh
chmod +x install_geographiclib_datasets.sh
sudo ./install_geographiclib_datasets.sh

八.安装功能包

启动yolov8环境编译  conda activate yolov8

删除build和devel后catkin_make 报错

1、pip install empy==3.3.4

2、pip install catkin_pkg

3.改yolomsg 地址  、 改视觉节点sys.ultralytics路径

九.测试视觉启动代码

roscore

cd yolov8_ws

conda activate yolov8

source ./devel/setup.bash

rosrun communication_yolo yolo_stablesend.py

25w 无RT加速 无int8量化大概35ms一帧

报错:

1、pip install rospkg

2、pip install lap

 十.TensorRT加速

预处理:

将jetpack安装的tensorrt 软连接至你的虚拟环境

1)退出虚拟环境查看tensorrt地址

python3.8 -c "import tensorrt; print(tensorrt.__file__)"

2)建立软连接

ln -s /usr/lib/python3.8/dist-packages/tensorrt /home/zzb/anaconda3/envs/yolov8_trt/lib/python3.8/site-packages/tensorrt

1、转onnx

pip install onnx==1.12.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

pip install onnxruntime -i https://pypi.tuna.tsinghua.edu.cn/simple

pip install polygraphy

2、量化

修改:

L289  onnx路径

L291 标定数据图片  一般用train图片

L300 模型验证图片  一般用val图片

L266数据集yaml路径  验证模型

L56 改数据集yaml路径  获取name类型

L13修改ultralytics路径
 

报错:

1)numpy has no attribute bool

找到报错文件

/home/zzb/anaconda3/envs/yolov8_trt/lib/python3.8/site-packages/tensorrt/__init__.py

 L166修改bool为bool_


int8 code:

#! /usr/bin/env python3import json
import os
import pathlib
from datetime import datetime
import cv2 as cv
import numpy as np
import onnxruntime
# 注意!必须先导入 YOLO,然后再导入 trt,否则在运行 validate_model 函数时,程序会被中断,并
# 报错 “Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)”
import sys
sys.path.append("/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/ultralytics")
from ultralytics import YOLO
import tensorrt as trt
from tqdm import tqdmfrom polygraphy.backend.trt import NetworkFromOnnxPath, CreateConfig, EngineFromNetwork
from polygraphy.backend.trt import Calibrator
import yamldef _yolo8_2_onnx(pt_model_path):"""把 YOLOv8 模型从 .pt 格式转换为 ONNX 模型。Arguments:pt_model_path (str): 训练好的 YOLOv8 detection (.pt)模型的权重路径。"""# check up wheather this pt_path exists '''expanduser():路径中包含~,它会被替换为当前用户的主目录的绝对路径pathlib.Path(pt_model_path):这里使用了pathlib库中的Path类来创建一个Path对象.resolve():resolve()方法将路径转换为其绝对形式'''pt_model_path = pathlib.Path(pt_model_path).expanduser().resolve()if not pt_model_path.exists():raise FileNotFoundError(f'Model not found: {pt_model_path}')print(f'{pt_model_path= }')model = YOLO(pt_model_path)model.export(format='onnx',opset=12)onnx_model_name = pt_model_path.stem + '.onnx'onnx_model = pt_model_path.parent / onnx_model_nameprint(f'Done! Model is exported as {onnx_model}')def _get_metadata():"""生成 metadata,这个 metadata 将被用于 YOLOv8 的 TensorRT 模型。如果是在 Anaconda 虚拟环境中安装的 YOLOv8 ,可以参考官方源码 exporter.py:~/.conda/envs/yolo8/lib/python3.10/site-packages/ultralytics/engine/exporter.py:return:metadata (dict): 一个字典,包含了 YOLOv8 的 TensorRT 模型所需的元数据。"""description = f'Ultralytics YOLOv8n model'# names: 表示类型与名字的对应关系,记得路径参数以获得names数据,如:E:\\ultralytics\\ultralytics\\cfg\\datasets\\coco128.yaml'with open("//home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/Datasets/target_train/Dataset.yaml", 'r', encoding="utf-8") as f:name = yaml.safe_load(f.read())names = name['names']metadata = {'description': description,'author': 'Ultralytics','license': 'AGPL-3.0 https://ultralytics.com/license','date': datetime.now().isoformat(),'version': '8.0.186','stride': 32,'task': 'detect','batch': 1,'imgsz': [640, 640],'names': names}return metadatadef _calib_data_yolo8(onnx_input_name, onnx_input_shape,calibration_images_quantity, calibration_images_folder):"""生成标定数据,用于对 YOLOv8 模型进行 int8 量化。为了有更好的量化效果,得到更好的比例值 scale,需要进行标定。标定时一般有 2 个要求:a. 标定数据是经过前处理之后的图片(通常是归一化之后的 [0, 1] 之间的数)。b. 标定数据应该使用实际的图片,比如训练集的图片。Arguments:onnx_input_name (str): 一个字符串,是 ONNX 模型输入的名字。onnx_input_shape (tuple(int, int, int, int)): 一个元祖,是 ONNX 模型的输入张量的形状。calibration_images_quantity (int): 一个整数,是标定时使用的图片数量。calibration_images_folder (str): 一个字符串,指向一个文件夹,该文件夹内的图片将被用于标定。:returnone_batch_data (Generator[dict[str, ndarray]]): 一个字典,包含了一个批次的标定数据。"""print(f' {onnx_input_shape= }')  #if onnx_input_shape[1] != 3:  # ONNX 输入的形状可以是:1, 3, 1504, 1504。第一维度是深度通道。raise ValueError(f'Error, expected input depth is 3, 'f'but {onnx_input_shape= }')calibration_images_folder = pathlib.Path(calibration_images_folder).expanduser().resolve()if not calibration_images_folder.exists():raise FileNotFoundError(f'{calibration_images_folder} does not exist.')print(f'{calibration_images_folder= }')batch_size = onnx_input_shape[0]required_height = onnx_input_shape[2]required_width = onnx_input_shape[3]# 初始化第 0 批数据。标定时必须给 engine 输入 FP32 格式的数据。output_images = np.zeros(shape=onnx_input_shape, dtype=np.float32)# 如果图片总数不够,则使用所有图片进行标定。calibration_images_quantity = min(calibration_images_quantity,len(os.listdir(calibration_images_folder)))print(f'Calibration images quantity: {calibration_images_quantity}')print(f'Calibrating ...')# 创建一个进度条。tqdm_images_folder = tqdm(calibration_images_folder.iterdir(),total=calibration_images_quantity, ncols=80)for i, one_image_path in enumerate(tqdm_images_folder):# 只有一个循环完整结束后,tqdm 进度条才会前进一格。因此要在 for 循环的开头# 使用 i == calibration_images_quantity 作为停止条件,才能看到完整的 tqdm 进度条if i == calibration_images_quantity:breakbgr_image = cv.imread(str(one_image_path))  # noqa# 改变图片尺寸,注意是宽度 width 在前。bgr_image = cv.resize(bgr_image, (required_width, required_height))  # noqaone_rgb_image = bgr_image[..., ::-1]  # 从 bgr 转换到 rgbone_image = one_rgb_image / 255  # 归一化,转换到 [0, 1]one_image = one_image.transpose(2, 0, 1)  # 形状变为 depth, height, widthbatch_index = i % batch_size  # 该批次数据中的索引位置output_images[batch_index] = one_image  # 把该图片放入到该批次数据的对应位置。if batch_index == (batch_size - 1):  # 此时一个 batch 的数据已经准备完成one_batch_data = {onnx_input_name: output_images}yield one_batch_data  # 以生成器 generator 的形式输出数据output_images = np.zeros_like(output_images)  # 初始化下一批次数据。def onnx_2_trt_by_polygraphy(onnx_file, optimization_level=2,conversion_target='int8', engine_suffix='engine',calibration_method='min-max', calibration_images_quantity=64,calibration_images_folder=None,onnx_input_shape=None):"""把 onnx 模型转换为 TensorRT 模型。可以进行 int8 量化,也可以转换为 FP16 格式的模型。Arguments:onnx_file (str | pathlib.Path): 一个字符串或 Path 对象,指向一个 ONNX 文件。optimization_level (int): 一个整数,代表优化等级。level 越大,则会花更多时间对 engine 进行优化,得到的 engine 性能有可能会更好。conversion_target (str): 一个字符串,是 'int8', 'fp16' 或者 'fp32'。int8 表示进行 int8 量化,而 fp16、fp32 则表示转换为 FP16 或 FP32 格式的 TensorRT 模型。engine_suffix (str): 是输出的 TensorRT 模型的文件名后缀,可以是 'plan' 、'engine' 或 'trt'。calibration_method (str): 是进行 int8 量化时的标定方法。如果输入 None,则使用默认的entropy 方法,如果输入 min-max,则使用 min-max 标定方法。calibration_images_quantity (int): 一个整数,是标定时使用的图片数量,只在 int8 量化时有效。onnx_input_shape (tuple(int, int, int, int) | None): 一个元祖,是 ONNX 模型的输入张量的形状。:returnconverted_trt (str): 一个字符串,是生成的 TensorRT 模型的绝对路径。"""if conversion_target.lower() not in ['int8', 'fp16', 'fp32']:raise ValueError(f"The conversion_target must be one of ['int8', 'fp16', 'fp32'], "f"but get {conversion_target= }")if engine_suffix not in ['plan', 'engine', 'trt']:raise ValueError(f"The engine_suffix must be one of ['plan', 'engine', 'trt'], "f"but get {engine_suffix= }")onnx_file = pathlib.Path(onnx_file).expanduser().resolve()if not onnx_file.exists():raise FileNotFoundError(f'Onnx file not found: {onnx_file}')print(f"Succeeded finding ONNX file! {onnx_file= }")print(f'Polygraphy inspecting model:')os.system(f"polygraphy inspect model {onnx_file}")  # 用 polygraphy 查看 ONNX 模型network = NetworkFromOnnxPath(str(onnx_file))  # 必须输入字符串给 NetworkFromOnnxPath# 1. 准备转换 engine 文件时的配置。包括 optimization_level 和 flag 等。#builder_config = CreateConfig(builder_optimization_level=optimization_level)builder_config = CreateConfig()print(f'{builder_config.builder_optimization_level= }')converted_trt_name = (f"{onnx_file.stem}_optimization_level_{optimization_level}"f"_{conversion_target}")if conversion_target.lower() == 'fp16':builder_config.fp16 = Trueprint(f'{builder_config.fp16= }')elif conversion_target.lower() == 'int8':# 2. 准备 int8 量化所需的 5 个配置。# 2.1 设置 INT8 的 flagbuilder_config.int8 = Trueprint(f'{builder_config.int8= }')# 2.2 用 onnxruntime 获取模型输入的名字和形状.session = onnxruntime.InferenceSession(onnx_file, providers=['CPUExecutionProvider'])onnx_input_name = session.get_inputs()[0].nameif onnx_input_shape is None:  # 查询 ONNX 中的输入张量形状。onnx_input_shape = session.get_inputs()[0].shape# 2.3 准备标定用的 cache 文件。if conversion_target.lower() == 'fp16':calibration_cache_file = f"./{onnx_file.stem}_fp16.cache"else :calibration_cache_file = f"./{onnx_file.stem}_int8.cache"calibration_cache_file = pathlib.Path(calibration_cache_file).expanduser().resolve()if calibration_cache_file.exists():  # 始终使用一个新的 cache,才能每次都生成新的 TensorRT 模型。os.remove(calibration_cache_file)# 2.4 设置标定方法。实际验证发现,对于 YOLOv8 模型,IInt8MinMaxCalibrator 标定的效果最好。if calibration_method == 'min-max':calibrator_class = trt.IInt8MinMaxCalibratorelse:# 默认使用 entropy 方法,该方法通过减少量化时的信息损失 information loss,对模型进行标定。calibrator_class = trt.IInt8EntropyCalibrator2# 2.5 在 Calibrator 类中,传入标定方法,标定数据和 cache 等。builder_config.calibrator = Calibrator(BaseClass=calibrator_class,data_loader=_calib_data_yolo8(onnx_input_name=onnx_input_name, onnx_input_shape=onnx_input_shape,calibration_images_quantity=calibration_images_quantity,calibration_images_folder=calibration_images_folder),cache=calibration_cache_file)int8_suffix = f'_{calibration_method}_images{calibration_images_quantity}'converted_trt_name = converted_trt_name + int8_suffixconverted_trt = onnx_file.parent / (converted_trt_name + f'.{engine_suffix}')print('Building the engine ...')# 3. 按照前面的配置 config,设置 engine。注意 EngineFromNetwork 返回的是一个可调用对象 callable。build_engine = EngineFromNetwork(network, config=builder_config)# 4. 调用一次 build_engine,即可生成 engine,然后保存 TensorRT 模型即可。with build_engine() as engine, open(converted_trt, 'wb') as t:yolo8_metadata = _get_metadata()  # 需要创建 YOLOv8 的原数据 metadatameta = json.dumps(yolo8_metadata)  # 转换为 json 格式的字符串# 保存 TensorRT 模型时,必须先写入 metadata,然后再写入模型的数据。t.write(len(meta).to_bytes(4, byteorder='little', signed=True))t.write(meta.encode())t.write(engine.serialize())engine_saved = ''if not pathlib.Path(converted_trt).exists():engine_saved = 'not 'print(f'Done! {converted_trt} is {engine_saved.upper()}saved.')return str(converted_trt)def validate_model(model_path, conf, iou, imgsz, dataset_split, agnostic_nms,batch_size=1,  **kwargs):"""验证 YOLOv8 模型的指标。可以是 TensorRT 模型或 PyTorch 的模型。Arguments:model_path (str): 一个字符串,是一个训练好的 YOLOv8 detection 模型的路径。conf (float): 一个范围在 [0, 1] 的浮点数,表示在预测时,使用的置信度阈值。iou (float): 一个范围在 [0, 1] 的浮点数,表示在预测时,使用的交并比。imgsz (int): 一个整数,是预测时,使用的图片最大高度和最大高度。dataset_split (str): 一个字符串,是 val 或 test,分别代表验证集或测试集。如果使用 val_test,必须把标签和图片都放入同一个文件夹 val_test 中。agnostic_nms (bool): 一个布尔值,如果为 True,则在进行 NMS 时,不区分类别,即把所有类别都看做同一个类别。而如果为 False,则只有相同类别的框,才会用来进行 NMS。batch_size (int): 一个整数,是预测时的 batch 大小。"""model_path = pathlib.Path(model_path).expanduser().resolve()if not model_path.exists():raise FileNotFoundError(f'Model not found: {model_path}')print(f'{model_path= }')print(f'{conf= }, {iou= }, {imgsz= }')model = YOLO(model_path, task='detect')  # 须在创建模型时设置 task。detect_data = "/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/Datasets/target_train/Dataset.yaml"metrics = model.val(split=dataset_split, save=False,data=detect_data,agnostic_nms=agnostic_nms, batch=batch_size,conf=conf, iou=iou, imgsz=imgsz,**kwargs)map50 = round(metrics.box.map50, 3)print(f'{dataset_split} mAP50= {map50}')def main():"""把 YOLOv8 模型进行 int8 量化,然后用验证集、测试集的数据,验证量化后模型的指标。一共有 3 个步骤,第一个步骤是把 pt 模型转换为 ONNX 模型,第二个步骤是进行 int8 量化,第三个步骤是验证量化模型的指标。注意第一个步骤要和后面两个步骤分开执行。即先注释第二步和第三步,执行第一步转换 ONNX 模型。然后将第一步注释掉,再次运行 main 程序,执行后面的第二步和第三步。"""# 1. 先用下面 2 行,把 PyTorch 模型转换为 ONNX 模型。# pt_model_path = ('/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/Datasets/target_train/12.19_GM_best.pt')# _yolo8_2_onnx(pt_model_path=pt_model_path)# 2. 用 ONNX 模型进行 int8 量化,生成 TensorRT 的模型。onnx_file = ("/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/Datasets/target_train/12.19_GM_best.onnx")calibration_images = 64  # 也可以尝试 100, 32 等其它图片数量进行标定。calibration_images_folder = "/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/Datasets/target_train/images/train"  # 使用训练集的图片进行标定。saved_engine = onnx_2_trt_by_polygraphy(onnx_file=onnx_file, optimization_level=2, conversion_target='int8',engine_suffix='engine', calibration_images_quantity=calibration_images,calibration_images_folder=calibration_images_folder)# 3. 用验证集和测试集,检查 int8 量化后的模型指标。# 也可以输入 pt_model_path 验证 PyTorch 模型的指标。validate_model(model_path=saved_engine,dataset_split="val_test", imgsz=640,conf=0.5, iou=0.7, agnostic_nms=True)if __name__ == '__main__':main()

100%|███████████████████████████████████████████| 64/64 [00:55<00:00,  1.14it/s]
[I] Saving calibration cache to /home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/12.19_GM_best_int8.cache
[W] Missing scale and zero-point for tensor (Unnamed Layer* 347) [Constant]_output, expect fall back to non-int8 implementation for any layer consuming or producing given tensor
[I] Finished engine building in 532.004 seconds
Done! /home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/Datasets/target_train/12.19_GM_best_optimization_level_2_int8_min-max_images64.engine is saved.
model_path= PosixPath('/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/Datasets/target_train/12.19_GM_best_optimization_level_2_int8_min-max_images64.engine')
conf= 0.5, iou= 0.7, imgsz= 640
Ultralytics YOLOv8.0.218 🚀 Python-3.8.20 torch-2.0.0+nv23.05 CUDA:0 (Orin, 15503MiB)
Loading /home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/Datasets/target_train/12.19_GM_best_optimization_level_2_int8_min-max_images64.engine for TensorRT inference...
[12/26/2024-19:14:38] [TRT] [I] The logger passed into createInferRuntime differs from one already provided for an existing builder, runtime, or refitter. Uses of the global logger, returned by nvinfer1::getLogger(), will return the existing value.

[12/26/2024-19:14:38] [TRT] [I] Loaded engine size: 4 MiB
[12/26/2024-19:14:38] [TRT] [I] [MemUsageChange] TensorRT-managed allocation in engine deserialization: CPU +0, GPU +4, now: CPU 0, GPU 4 (MiB)
[12/26/2024-19:14:38] [TRT] [I] [MemUsageChange] TensorRT-managed allocation in IExecutionContext creation: CPU +0, GPU +28, now: CPU 0, GPU 32 (MiB)
Traceback (most recent call last):
  File "/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/ultralytics/data/base.py", line 104, in get_img_files
    p = Path(p)  # os-agnostic
  File "/home/zzb/anaconda3/envs/yolov8_trt/lib/python3.8/pathlib.py", line 1042, in __new__
    self = cls._from_parts(args, init=False)
  File "/home/zzb/anaconda3/envs/yolov8_trt/lib/python3.8/pathlib.py", line 683, in _from_parts
    drv, root, parts = self._parse_args(args)
  File "/home/zzb/anaconda3/envs/yolov8_trt/lib/python3.8/pathlib.py", line 667, in _parse_args
    a = os.fspath(a)
TypeError: expected str, bytes or os.PathLike object, not NoneType

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "TensorRT_int8.py", line 306, in <module>
    main()
  File "TensorRT_int8.py", line 299, in main
    validate_model(model_path=saved_engine,
  File "TensorRT_int8.py", line 267, in validate_model
    metrics = model.val(split=dataset_split, save=False,
  File "/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/ultralytics/engine/model.py", line 273, in val
    validator(model=self.model)
  File "/home/zzb/.local/lib/python3.8/site-packages/torch/utils/_contextlib.py", line 115, in decorate_context
    return func(*args, **kwargs)
  File "/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/ultralytics/engine/validator.py", line 150, in __call__
    self.dataloader = self.dataloader or self.get_dataloader(self.data.get(self.args.split), self.args.batch)
  File "/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/ultralytics/models/yolo/detect/val.py", line 197, in get_dataloader
    dataset = self.build_dataset(dataset_path, batch=batch_size, mode='val')
  File "/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/ultralytics/models/yolo/detect/val.py", line 193, in build_dataset
    return build_yolo_dataset(self.args, img_path, batch, self.data, mode=mode, stride=self.stride)
  File "/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/ultralytics/data/build.py", line 80, in build_yolo_dataset
    return YOLODataset(
  File "/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/ultralytics/data/dataset.py", line 41, in __init__
    super().__init__(*args, **kwargs)
  File "/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/ultralytics/data/base.py", line 72, in __init__
    self.im_files = self.get_img_files(self.img_path)
  File "/home/zzb/yolov8_ws/src/communication_yolo/yolov8_main/ultralytics/data/base.py", line 120, in get_img_files
    raise FileNotFoundError(f'{self.prefix}Error loading data from {img_path}\n{HELP_URL}') from e
FileNotFoundError: val: Error loading data from None
See https://docs.ultralytics.com/datasets/detect for dataset formatting guidance.

相关文章:

jetson Orin nx + yolov8 TensorRT 加速量化 环境配置

参考【Jetson】Jetson Orin NX纯系统配置环境-CSDN博客 一 系统环境配置&#xff1a; 1.更换源&#xff1a; sudo vi /etc/apt/sources.list.d/nvidia-l4t-apt-source.list2.更新源&#xff1a; sudo apt upgradesudo apt updatesudo apt dist-upgrade sudo apt-get updat…...

Android Studio IDE环境配置

​需要安装哪些东西&#xff1a; Java jdk Java Downloads | OracleAndroid Studio 下载 Android Studio 和应用工具 - Android 开发者 | Android DevelopersAndroid Sdk 现在的Android Studio版本安装时会自动安装&#xff0c;需要注意下安装的路径Android Studio插件…...

PTA 7-2 0/1背包问题(回溯法) 作者 王东 单位 贵州师范学院

0/1背包问题。给定一载重量为W的背包及n个重量为wi、价值为vi的物体&#xff0c;1≤i≤n,要求重量和恰好为W具有最大的价值。 输入格式: 第一行输入背包载重量W及背包个数n&#xff0c;再依次输入n行&#xff0c;每行为背包重量wi和价值vi。 输出格式: 第一行输出装入背包内…...

Matlab环形柱状图

数据准备&#xff1a; 名称 数值 Aa 21 Bb 23 Cc 35 Dd 47 保存为Excel文件后&#xff1a; % Load data from Excel file filename data.xlsx; % Ensure the file is in the current folder or provide full path dataTable readtable(filena…...

【AI大模型】探索GPT模型的奥秘:引领自然语言处理的新纪元

目录 &#x1f354; GPT介绍 &#x1f354; GPT的架构 &#x1f354; GPT训练过程 3.1 无监督的预训练语言模型 3.2 有监督的下游任务fine-tunning &#x1f354; 小结 学习目标 了解什么是GPT.掌握GPT的架构.掌握GPT的预训练任务. &#x1f354; GPT介绍 GPT是OpenAI公…...

5.Python爬虫相关

爬虫 爬虫原理 爬虫&#xff0c;又称网络爬虫&#xff0c;是一种自动获取网页内容的程序。它模拟人类浏览网页的行为&#xff0c;发送HTTP请求&#xff0c;获取网页源代码&#xff0c;再通过解析、提取等技术手段&#xff0c;获取所需数据。 HTTP请求与响应过程 爬虫首先向…...

Windows系统上配置eNSP环境的详细步骤

华为eNSP&#xff08;Enterprise Network Simulation Platform&#xff09;是一款针对华为数通网络设备的网络仿真平台&#xff0c;用于辅助工程师进行网络技术学习、方案验证和故障排查等工作。以下是在Windows系统上配置eNSP环境的详细步骤&#xff1a; 1. 准备工作 下载安…...

Database.NET——一款轻量级多数据库客户端工具

文章目录 Database.NET简介下载使用使用场景总结 Database.NET简介 Database.NET 是一个功能强大且易于使用的数据库管理工具&#xff0c;适用于多种数据库系统。它为开发者和数据库管理员提供了一个统一的界面&#xff0c;可以方便地管理和操作不同类型的数据库。 支持的数据…...

新浪微博C++面试题及参考答案

多态是什么&#xff1f;请详细解释其实现原理&#xff0c;例如通过虚函数表实现。 多态是面向对象编程中的一个重要概念&#xff0c;它允许不同的对象对同一消息或函数调用做出不同的响应&#xff0c;使得程序具有更好的可扩展性和灵活性。 在 C 中&#xff0c;多态主要通过虚函…...

计算机视觉目标检测-1

文章目录 摘要Abstract1.目标检测任务描述1.1 目标检测分类算法1.2 目标定位的简单实现思路1.2.1 回归位置 2.R-CNN2.1 目标检测-Overfeat模型2.1.1 滑动窗口 2.2 目标检测-RCNN模型2.2.1 非极大抑制&#xff08;NMS&#xff09; 2.3 目标检测评价指标 3.SPPNet3.1 spatial pyr…...

【物联网技术与应用】实验15:电位器传感器实验

实验15 电位器传感器实验 【实验介绍】 电位器可以帮助控制Arduino板上的LED闪烁的时间间隔。 【实验组件】 ● Arduino Uno主板* 1 ● 电位器模块* 1 ● USB电缆*1 ● 面包板* 1 ● 9V方型电池* 1 ● 跳线若干 【实验原理】 模拟电位器是模拟电子元件&#xff0c;模…...

java常用类(上)

笔上得来终觉浅,绝知此事要躬行 &#x1f525; 个人主页&#xff1a;星云爱编程 &#x1f525; 所属专栏&#xff1a;javase &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 一、包装类 1.1包装类…...

包管理工具npm、yarn、pnpm、cnpm详解

1. 包管理工具 1.1 npm # 安装 $ node 自带 npm# 基本用法 npm install package # 安装包 npm install # 安装所有依赖 npm install -g package # 全局安装 npm uninstall package # 卸载包 npm update package # 更新包 npm run script #…...

CI/CD是什么?

CI/CD 定义 CI/CD 代表持续集成和持续部署&#xff08;或持续交付&#xff09;。它是一套实践和工具&#xff0c;旨在通过自动化构建、测试和部署来改进软件开发流程&#xff0c;使您能够更快、更可靠地交付代码更改。 持续集成 (CI)&#xff1a;在共享存储库中自动构建、测试…...

[Java]合理封装第三方工具包(附视频)

-1.视频链接 视频版: 视频版会对本文章内容进行详细解释 [Java]合理封装第三方工具包_哔哩哔哩_bilibili 0.核心思想 对第三方工具方法进行封装,使其本地化,降低记忆和使用成本 1.背景 在我们的项目中,通常会引用一些第三方工具包,或者是使用jdk自带的一些工具类 例如: c…...

常规配置、整合IDEA

目录 Redis常规配置 tcp-keepalive security Jedis RedisTemplate 连接池技术 Lua脚本 Jedis集群 Redis应用问题&解决方案 缓存穿透 缓存击穿 缓存雪崩 分布式锁 Redis实现分布式锁 Redis新功能 ACL Redis常规配置 tcp-keepalive security redis.conf中…...

用Python写炸金花游戏

文章目录 **代码分解与讲解**1. **扑克牌的生成与洗牌**2. **给玩家发牌**3. **打印玩家的手牌**4. **定义牌的优先级**5. **判断牌型**6. **确定牌型优先级**7. **比较两手牌的大小**8. **计算每个玩家的牌型并找出赢家**9. **打印结果** 完整代码 以下游戏规则&#xff1a; 那…...

计算机的错误计算(一百九十二)

摘要 用两个大模型计算 csc(0.999), 其中&#xff0c;0.999是以弧度为单位的角度&#xff0c;结果保留5位有效数字。两个大模型均给出了 Python代码与答案。但是&#xff0c;答案是错误的。 例1. 计算 csc(0.999), 其中&#xff0c;0.999是以弧度为单位的角度&#xff0c;结…...

37 Opencv SIFT 特征检测

文章目录 Ptr<SIFT> SIFT::create示例 Ptr SIFT::create Ptr<SIFT> SIFT::create(int nfeatures 0,int nOctaveLayers 3,double contrastThreshold 0.04,double edgeThreshold 10,double sigma 1.6 );参数说明&#xff1a;nfeatures&#xff1a;类型&#x…...

Nginx界的天花板-Oracle 中间件OHS 11g服务器环境搭建

环境信息 服务器基本信息 如下表&#xff0c;本次安装总共使用2台服务器&#xff0c;具体信息如下&#xff1a; 服务器IP DNS F5配置 OHS1 172.xx.xx.xx ohs01.xxxxxx.com ohs.xxxxxx.com OHS2 172.xx.xx.xx ohs02.xxxxxx.com 服务器用户角色信息均为&#xff1a;…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

网页端 js 读取发票里的二维码信息(图片和PDF格式)

起因 为了实现在报销流程中&#xff0c;发票不能重用的限制&#xff0c;发票上传后&#xff0c;希望能读出发票号&#xff0c;并记录发票号已用&#xff0c;下次不再可用于报销。 基于上面的需求&#xff0c;研究了OCR 的方式和读PDF的方式&#xff0c;实际是可行的&#xff…...