碎碎念
最近一直在忙毕业设计,头发又少了一点(悲)。期间要用到目标检测这一块,研究了一下PaddleYOLO,发现教程是真不多,很多坑也没人填,官方仓库里的很多说明文件也不存在了,需要自行摸索。边踩边填的过程虽然痛苦,但也算成功跑通了训练 + 部署的完整流程。为了防止下一次又一脸懵逼地重头开始,这里写个记录,也希望能帮到后来人。
顺带一提,PaddleYOLO≠PP-YOLO,不要搞混了。PaddleYOLO是飞桨官方的目标检测套件,相当于是集成了各种检测模型的训练与部署框架。它目前支持的模型包括YOLOv3、YOLOv5、PP-YOLO、PP-YOLOE,YOLO系列最新支持到了YOLOv8,本次训练我们也基于YOLOv8进行展开讲解。
**注意:**本篇文章可能稍微有些枯燥乏味,因为是以实验报告的内容,可能没有一些华丽的辞藻,更多是关于相关领域的一些术词,可能仅供专业人士研究。
介绍
PaddleYOLO是基于飞桨框架开发的目标检测套件,专注于整合和优化 YOLO 系列模型,旨在提供高性能、轻量级且易于部署的目标检测解决方案。
性能优势
- 高性能:
PaddleYOLO采用优化的计算图执行引擎,对模型进行了深度的硬件级优化,能够充分利用GPU和CPU资源,实现更快的推理速度。 - 轻量级:模型结构紧凑,适合资源受限的设备,如嵌入式系统或移动设备,支持实时目标检测。
- 灵活可扩展:支持多种
YOLO架构,包括YOLOv3、YOLOv5、YOLOv6、YOLOv7、YOLOv8、PP-YOLO、PP-YOLOE、RT-DETR等,用户可根据实际需求调整网络配置,适应不同应用场景。 - 易于部署:集成了
Paddle Serving,提供完整的模型服务解决方案,便于将模型部署到生产环境,具有良好的跨平台兼容性,支持在多种硬件平台上运行,包括昇腾NPU(比如我们学校那个B鲲鹏平台)。
模型支持列表
| 模型名称 | GitHub 仓库地址 |
|---|---|
| YOLOv3 | ultralytics/yolov3 |
| YOLOv5 | ultralytics/yolov5 |
| YOLOv6 | meituan/YOLOv6 |
| YOLOv7 | WongKinYiu/yolov7 |
| YOLOv8 | ultralytics/ultralytics |
| PP-YOLO | PaddlePaddle/PaddleDetection |
| PP-YOLOv2 | PaddlePaddle/PaddleDetection |
| PP-YOLOE | PaddlePaddle/PaddleDetection |
| PP-YOLOE+ | PaddlePaddle/PaddleDetection |
| RT-DETR | lyuwenyu/RT-DETR |
| YOLOX | Megvii-BaseDetection/YOLOX |
| YOLOv5u | ultralytics/yolov5 |
| YOLOv7u | WongKinYiu/yolov7 |
| YOLOv6Lite | meituan/YOLOv6 |
| RTMDet | open-mmlab/mmdetection |
MMYOLO对比
MMYOLO是基于OpenMMLab开发的目标检测框架,具有模块化设计,允许轻松定制和扩展,适合研究和开发新技术,相比之下,PaddleYOLO专注于飞桨生态系统,针对飞桨框架进行了优化,提供了高性能和轻量级的目标检测解决方案,特别适合需要与其他飞桨项目(如 PPOCR)集成的应用场景。在本项目的第二阶段,需要使用PPOCR进行文字检测与识别。为了保持框架的一致性,减少跨框架通信和转换的复杂性,在这里我选择了与PPOCR同属飞桨生态的PaddleYOLO作为目标检测模块。
下面我将详细了解一下如何使用PaddleYOLO进行训练内容。
环境配置
首先克隆PaddleYOLO仓库:
git clone https://github.com/PaddlePaddle/PaddleYOLO.git
cd PaddleYOLO
Python
首先创建一个Python环境,经过我测试,强烈建议3.10环境,可以最大的兼容,如果你使用的conda,使用以下命令:
conda create -n myenv python=3.10
conda activate myenv
创建环境后,安装一些依赖包:
pip install -r requirements.txt # install
下面需要安装PaddlePaddle。
PaddlePaddle
首先点击下方链接打开官网:
站外引用 · 引用站外地址,不保证站点的可用性和安全性飞桨新一代框架3.0源于产业实践的开源深度学习平台向下滑到快速安装部分,如果cuda没有合适的版本可以向上选择,执行命令的过程中可能会有很多报错,不要慌张,这都是因为依赖包的问题,按照要求安装对应包即可。
数据预处理
数据格式
在PaddleYOLO中,数据集是支持了三种格式的,分别为VOC、COCO和YOLO专用数据集,三者的格式分别如下:
-
VOC格式:
PASCAL VOC数据集的目录结构通常如下:VOCdevkit/ ├── VOC2007/ │ ├── Annotations/ # 存放 XML 格式的标注文件 │ ├── JPEGImages/ # 存放图像文件 │ ├── ImageSets/ │ │ └── Main/ │ │ ├── train.txt # 训练集文件名列表 │ │ ├── val.txt # 验证集文件名列表 │ │ └── test.txt # 测试集文件名列表在
Annotations/目录下,每个 XML 文件对应一张图像,包含该图像中目标的边界框、类别等信息。VOC格式是一个较为传统的数据结构,使用XML文件描述每张图片的标注信息,结构直观、易于阅读。著名标注工具LabelMe的结果就是VOC格式,在早期的目标检测任务中被程序员广泛使用,适合初学者入门和教学场景,但由于不够灵活,难以支持像分割或关键点检测这样的高级任务,现在的使用率已大幅下降。 -
COCO格式:
COCO数据集的目录结构示例如下:coco/ ├── annotations/ │ ├── instances_train2017.json # 训练集标注文件 │ ├── instances_val2017.json # 验证集标注文件 ├── images/ │ ├── train2017/ # 训练集图像 │ └── val2017/ # 验证集图像在
annotations/目录下,标注文件为 JSON 格式,包含图像信息、类别信息、目标的边界框等。在目标检测任务中,我们最常用且通用性最强的数据格式是COCO 格式。相比于
VOC和YOLO格式,COCO拥有更丰富的结构设计和信息表达能力,它不仅支持物体检测,还可以扩展到实例分割、关键点检测、多标签分类等任务,因此被广泛应用于商业级项目和科研场景。几乎所有主流的检测框架,包括MMDetection、YOLOv5/v8、PaddleYOLO等,都原生支持COCO格式的数据,使其在模型训练、测试和部署中都非常方便。 -
YOLO格式:
YOLO格式的数据集目录结构通常如下:yolo_dataset/ ├── images/ │ ├── train/ # 训练集图像 │ ├── val/ # 验证集图像 │ └── test/ # 测试集图像(可选) ├── labels/ │ ├── train/ # 训练集标注文件 │ ├── val/ # 验证集标注文件 │ └── test/ # 测试集标注文件(可选)在
labels/目录下,每个标注文件对应一张图像,采用纯文本格式,每行表示一个目标,包含类别索引、边界框中心坐标、宽度和高度,所有值均为归一化后的相对值。YOLO专用格式则以极简著称,每张图像对应一个.txt文件,每行标注一个目标,格式紧凑、易于解析,适合在资源受限或对实时性要求高的边缘设备中使用。不过,其表达能力有限,仅支持类别与边框信息,不适用于需要更复杂标注的任务,并且在一些检测框架中仍需手动转换为COCO格式才能使用。
因此,综合考虑框架兼容性、后续扩展性以及整体便携性,我个人更加推荐在PaddleYOLO中使用COCO格式的数据集。
数据准备
本次毕设我选择了船舶方向的研究,所以这里我采用了两个知名航海船舶数据集:Seaships和MCShips,链接如下:
这里我就以第一个为例,如果需要融合数据,只需要修改代码的类别数量即可。
格式转换
以上二者数据都是VOC格式的,这里我在网上找到了以下代码进行转换:
import os
import cv2
import json
import shutil
import xml.etree.ElementTree as ET
from tqdm import tqdm
# Seaships 数据集的类别
SEASHIPS_CLASSES = (
'ore carrier', 'bulk cargo carrier', 'general cargo ship', 'container ship', 'fishing boat', 'passenger ship'
# 'warship', 'civilianship'
)
# 将类别名称映射为 COCO 格式的 category_id
label_ids = {name: i + 1 for i, name in enumerate(SEASHIPS_CLASSES)}
def parse_xml(xml_path):
"""
解析 XML 文件,提取标注信息。
"""
tree = ET.parse(xml_path)
root = tree.getroot()
objects = []
for obj in root.findall('object'):
# 解析类别名称
name = obj.find('name').text
if name not in label_ids:
print(f"警告: 未知类别 '{name}',跳过该对象。")
continue
# 解析 difficult 标签
difficult_tag = obj.find('difficult')
difficult = int(difficult_tag.text) if difficult_tag is not None else 0
# 解析边界框
bnd_box = obj.find('bndbox')
if bnd_box is not None:
bbox = [
int(bnd_box.find('xmin').text),
int(bnd_box.find('ymin').text),
int(bnd_box.find('xmax').text),
int(bnd_box.find('ymax').text)
]
else:
print(f"警告: 在文件 {xml_path} 中未找到 <bndbox> 标签,跳过该对象。")
continue
# 添加到对象列表
objects.append({
'name': name,
'label_id': label_ids[name],
'difficult': difficult,
'bbox': bbox
})
return objects
def load_split_files(split_dir):
"""
加载划分文件(train.txt, val.txt, test.txt)。
"""
split_files = {}
for split_name in ['train', 'val', 'test']:
split_path = os.path.join(split_dir, f'{split_name}.txt')
if os.path.exists(split_path):
with open(split_path, 'r') as f:
split_files[split_name] = [line.strip() for line in f.readlines()]
else:
print(f"警告: 未找到 {split_name}.txt 文件,跳过该划分。")
split_files[split_name] = []
return split_files
def convert_to_coco(image_dir, xml_dir, split_dir, output_dir):
"""
将 Seaships 数据集转换为 COCO 格式,并根据划分文件划分数据集。
"""
# 创建输出目录
os.makedirs(os.path.join(output_dir, 'annotations'), exist_ok=True)
os.makedirs(os.path.join(output_dir, 'train'), exist_ok=True)
os.makedirs(os.path.join(output_dir, 'val'), exist_ok=True)
os.makedirs(os.path.join(output_dir, 'test'), exist_ok=True)
# 加载划分文件
split_files = load_split_files(split_dir)
# 定义 COCO 格式的基本结构
def create_coco_structure():
return {
"info": {
"description": "Seaships Dataset",
"version": "1.0",
"year": 2023,
"contributor": "Your Name",
"date_created": "2023-10-01"
},
"licenses": [],
"images": [],
"annotations": [],
"categories": [
{"id": i + 1, "name": name, "supercategory": "none"}
for i, name in enumerate(SEASHIPS_CLASSES)
]
}
# 处理每个数据集
for split_name, file_names in split_files.items():
coco_data = create_coco_structure()
annotation_id = 1
for file_name in tqdm(file_names, desc=f"处理 {split_name} 数据集"):
xml_file = os.path.join(xml_dir, f'{file_name}.xml')
image_name = f'{file_name}.jpg'
image_path = os.path.join(image_dir, image_name)
# 检查图像文件和 XML 文件是否存在
if not os.path.exists(image_path):
print(f"警告: 图像文件 {image_name} 不存在,跳过该标注文件。")
continue
if not os.path.exists(xml_file):
print(f"警告: 标注文件 {xml_file} 不存在,跳过该图像文件。")
continue
# 读取图像尺寸
image = cv2.imread(image_path)
height, width, _ = image.shape
# 添加图像信息
image_id = len(coco_data['images']) + 1
coco_data['images'].append({
"id": image_id,
"file_name": image_name,
"width": width,
"height": height
})
# 解析 XML 文件
objects = parse_xml(xml_file)
for obj in objects:
xmin, ymin, xmax, ymax = obj['bbox']
bbox = [xmin, ymin, xmax - xmin, ymax - ymin] # COCO 格式的 bbox 是 [x, y, width, height]
area = (xmax - xmin) * (ymax - ymin)
coco_data['annotations'].append({
"id": annotation_id,
"image_id": image_id,
"category_id": obj['label_id'],
"bbox": bbox,
"area": area,
"iscrowd": 0,
"difficult": obj['difficult']
})
annotation_id += 1
# 复制图像文件到对应的文件夹
shutil.copy(image_path, os.path.join(output_dir, split_name, image_name))
# 保存 COCO 格式的标注文件
with open(os.path.join(output_dir, 'annotations', f'instances_{split_name}.json'), 'w') as f:
json.dump(coco_data, f, indent=4)
print(f"转换完成,结果已保存到 {output_dir}")
# 设置路径
image_dir = ".\dataset\Mcship_lite\JPEGImages" # 图像文件目录
xml_dir = ".\dataset\Mcship_lite\Annotations" # XML 标注文件目录
split_dir = ".\dataset\Mcship_lite\ImageSets\Main" # 划分文件目录(包含 train.txt, val.txt, test.txt)
output_dir = ".\dataset\Mcship_lite-coco" # 输出的 COCO 格式文件夹
# 执行转换
convert_to_coco(image_dir, xml_dir, split_dir, output_dir)
只需要修改下面的路径即可,最终会直接输出标准格式的COCO数据集,这样我们的数据预处理部分也就实现了。
调整配置
下面我们需要修改一些配置,通过配置,正确的指向我们所需要的模型,数据。
数据库配置
首先配置数据库,为了方便,我们将数据库放置在了PaddleYOLO/dataset文件夹内,然后开始配置,如果文件克隆完整,我们可以在PaddleYOLO/configs/datasets目录下看到一些数据集配置:
PaddleYOLO/
├── configs/
│ ├── datasets/
│ │ ├── Coco_Detection.yml # 配置 COCO 数据集,用于物体检测任务
│ │ ├── Coco_instance.yml # 配置 COCO 数据集的实例分割任务
│ │ ├── object365_Detection.yml # 配置 Object365 数据集,用于多类物体检测任务
│ │ ├── OpenImagesv7_Detection.yml # 配置 Open Images v7 数据集,用于大规模目标检测任务
│ │ ├── roadsign_voc.yml # 配置 RoadSign 数据集,用于交通标志检测任务,兼容 VOC 格式
│ │ ├── Visdrone_Detection.yml # 配置 VisDrone 数据集,用于无人机图像物体检测与追踪
│ │ └── Voc.yml # 配置 PASCAL VOC 数据集,用于传统物体检测任务
按照我们的要求,我们进行的是船舶识别检测,所以选择第一个配置文件作为基础文件,复制该文件,比如这里我是创建了一个Coco_Detection_Mydataset.yml文件,存储我个人的数据集配置,内容如下:
metric: COCO
num_classes: 6
TrainDataset:
name: COCODataSet
image_dir: train
anno_path: annotations/instances_train.json
dataset_dir: dataset/SeaShips-coco
data_fields: ["image", "gt_bbox", "gt_class", "is_crowd"]
EvalDataset:
name: COCODataSet
image_dir: val
anno_path: annotations/instances_val.json # annotations/instances_val.json
dataset_dir: dataset/SeaShips-coco
TestDataset:
name: ImageFolder
image_dir: test # test
anno_path: annotations/instances_test.json # annotations/instances_val.json # also support txt (like VOC's label_list.txt)
dataset_dir: dataset/SeaShips-coco # if set, anno_path will be 'dataset_dir/anno_path'
需要修改的内容是第二行的类别,和每个里面的路径和地址,这里用的相对地址,注意个人存放路径,其他不要修改。
训练配置
这里我用的是YOLOv8,并且选择了M*版本模型,是一个兼顾速度和效果的版本,找到目录PaddleYOLO\configs\yolov8,目录如下:
PaddleYOLO/
├── configs/
│ ├── yolov8/
│ │ ├── _base_
│ │ ├── openimagev7 # 配置 OpenImages v7 数据集的 YOLOv8 训练
│ │ ├── README.md # 该文件包含 YOLOv8 配置的说明和使用方法
│ │ ├── yolov8_l_500e_coco.yml # 配置 YOLOv8 使用 COCO 数据集,训练 500 epochs,模型为 L 版本
│ │ ├── yolov8_m_500e_coco.yml # 配置 YOLOv8 使用 COCO 数据集,训练 500 epochs,模型为 M 版本
│ │ ├── yolov8_n_500e_coco.yml # 配置 YOLOv8 使用 COCO 数据集,训练 500 epochs,模型为 N 版本
│ │ ├── yolov8_s_500e_coco.yml # 配置 YOLOv8 使用 COCO 数据集,训练 500 epochs,模型为 S 版本
│ │ ├── yolov8_x_500e_coco.yml # 配置 YOLOv8 使用 COCO 数据集,训练 500 epochs,模型为 X 版本
│ │ └── yolov8p6_x_500e_coco.yml # 配置 YOLOv8p6 使用 COCO 数据集,训练 500 epochs,模型为 X 版本
以上不同的配置文件表示不同的模型版本,以下是这些配置文件的简要说明:
| 配置文件 | 模型版本 | 训练数据集 | 训练周期 | 说明 |
|---|---|---|---|---|
yolov8_l_500e_coco.yml | L 版本 | COCO | 500 epochs | YOLOv8 L 版本,适合高精度任务,计算资源需求较高。 |
yolov8_m_500e_coco.yml | M 版本 | COCO | 500 epochs | YOLOv8 M 版本,精度与速度平衡,适中任务。 |
yolov8_n_500e_coco.yml | N 版本 | COCO | 500 epochs | YOLOv8 N 版本,适合资源有限的环境,速度较快。 |
yolov8_s_500e_coco.yml | S 版本 | COCO | 500 epochs | YOLOv8 S 版本,适合较小任务,计算资源要求低。 |
yolov8_x_500e_coco.yml | X 版本 | COCO | 500 epochs | YOLOv8 X 版本,精度较高,适用于复杂任务。 |
yolov8p6_x_500e_coco.yml | X 版本(P6) | COCO | 500 epochs | YOLOv8p6 X 版本,优化精度和性能,适合高精度应用。 |
这些版本的区别主要在于模型大小、精度与计算资源需求的平衡,按照自己的需求选择即可,选哪个都可以运行,训练周期我们是可以控制的。
这里我需要配置m版本模型,为了防止破坏项目结构,新建一个文件放置我自己的配置文件,比如yolov8_m_500e_coco_mydataset.yml,内容如下:
_BASE_:
[
"../datasets/coco_detection_mydataset.yml",
"../runtime.yml",
"_base_/optimizer_500e_high_mydataset.yml",
"_base_/yolov8_cspdarknet.yml",
"_base_/yolov8_reader_high_aug.yml",
]
depth_mult: 0.67
width_mult: 0.75
log_iter: 50
snapshot_epoch: 5
weights: output/yolov8_m_500e_coco/model_final
YOLOv8CSPDarkNet:
last_stage_ch: 768 # The actual channel is int(768 * width_mult), not int(1024 * width_mult) as in YOLOv5
TrainReader:
batch_size: 8 # default 8 gpus, total bs = 128
在第一个_BASE_部分指定该配置文件引用了一些其他的配置,比如第一个是数据集配置文件,第二个为配置和管理模型训练或推理时的运行时环境参数配置文件,第三个为优化器配置文件,第四个为使用CSPDarkNet网络架构配置文件,第五个为数据加载起配置文件,这里我们只需要修改第一个和第三个,其余的如果熟练的话,可以按照自己的要求进行定制,第一个指向前面我们修改的数据集配置文件,第三个指定了一些学习率和学习率增量等一些配置。
我们先看上面的训练配置文件,其中配置作用如下:
- depth_mult:
控制网络深度的缩放比例。
0.67表示将网络的层数减少到原来的67%,从而减少模型的复杂度和计算量,但可能会影响模型的精度。 - width_mult:
控制网络宽度的缩放比例。
0.75表示将网络每层的通道数减少到原来的75%,从而减少模型的参数量和计算复杂度,但可能也会影响性能。 - log_iter:
设置日志输出的频率。
50表示每经过50次训练迭代就记录一次日志信息。这有助于监控训练进度、损失变化和其他重要指标。 - snapshot_epoch:
设置模型保存的频率。
5表示每训练5个epoch保存一次模型,以便在训练过程中进行检查点保存,便于恢复或调优。 - weights:
指定预训练模型的路径,
output/yolov8_m_500e_coco/model_final指向预训练的权重文件。这些预训练权重有助于加速收敛,特别是在类似任务的微调过程中。 - YOLOv8CSPDarkNet:
- last_stage_ch:
设置
YOLOv8 CSPDarkNet模型最后一层的通道数。768是实际通道数(在应用了width_mult后是int(768 * 0.75) = 576)。这个参数决定了特征提取网络的宽度,影响模型的复杂度和性能。
- last_stage_ch:
设置
- TrainReader:
- batch_size:
设置每个 GPU 上的批处理大小。
8表示每个GPU在一次迭代中处理 8 个样本。如果使用多个GPU,总批处理大小会更大,当然如果算力有限,那就越小越好啦!
- batch_size:
设置每个 GPU 上的批处理大小。
优化器配置
这里其实没什么好说的,主要能修改的就是学习率和轮次了,这个都需要按照自己的项目需求进行修改,我这里就简单测试一下,后续会上算力机器进行训练,所以简单训练个50轮即可,该文件就是上面_BASE_配置中第三个配置文件。
# epoch: 50
LearningRate:
base_lr: 0.005
schedulers:
- !YOLOv5LRDecay
max_epochs: 500
min_lr_ratio: 0.1 #
- !ExpWarmup
epochs: 5 #3
OptimizerBuilder:
optimizer:
type: Momentum
momentum: 0.937
use_nesterov: True
regularizer:
factor: 0.0005
type: L2
clip_grad_by_value: 10.
到了目前,所有的配置基本结束,下面开始训练。
训练和测试
这里其实就是一个命令的事情,所以我按照官网的说法,实现了一个bat文件,按照自己的要求进行注释和打开注释即可运行:
@echo off
setlocal enabledelayedexpansion
:: 设置模型名称和作业名称
set model_name=yolov8
set job_name=yolov8_m_500e_coco_mydataset
set config=configs\%model_name%\%job_name%.yml
set log_dir=log_dir\%job_name%
set weights=output\%job_name%\model_final.pdparams
:: 1. 训练(单卡/多卡),加 --eval 表示边训边评估,加 --amp 表示混合精度训练
set CUDA_VISIBLE_DEVICES=0
python -m paddle.distributed.launch --log_dir=%log_dir% --gpus 0 tools/train.py -c %config% --eval --amp --use_vdl True --vdl_log_dir=vdl_dir/scalar -o pretrain_weights=./models/yolov8_m_500e_coco.pdparams
:: 2. 评估,加 --classwise 表示输出每一类mAP
:: python tools/eval.py -c %config% -o weights=%weights% --classwise
:: 3. 预测(单张图/图片文件夹)
python tools/infer.py -c %config% -o weights=%weights% --infer_img=./dataset/MyDataSet-coco/train/000002.jpg --draw_threshold=0.2
:: python tools/infer.py -c %config% -o weights=%weights% --infer_dir=demo\ --draw_threshold=0.5
:: 4. 导出模型,以下3种模式选一种
:: 普通导出
:: python tools/export_model.py -c %config% -o weights=%weights%
:: exclude_post_process 去除后处理导出,返回和 YOLOv5 导出 ONNX 时相同格式的 concat 后的 1 个 Tensor
:: python tools/export_model.py -c %config% -o weights=%weights% exclude_post_process=True
:: exclude_nms 去除 NMS 导出,返回 2 个 Tensor
:: python tools/export_model.py -c %config% -o weights=%weights% exclude_nms=True
:: 5. 部署预测
:: python deploy/python/infer.py --model_dir=output_inference\%job_name% --image_file=demo\000000014439_640x640.jpg --device=GPU
:: 6. 部署测速,加 “--run_mode=trt_fp16” 表示在 TensorRT FP16 模式下测速
:: python deploy/python/infer.py --model_dir=output_inference\%job_name% --image_file=demo\000000014439_640x640.jpg --device=GPU --run_benchmark=True
:: 7. ONNX 导出
:: paddle2onnx --model_dir output_inference\%job_name% --model_filename model.pdmodel --params_filename model.pdiparams --opset_version 12 --save_file %job_name%.onnx
:: 8. ONNX TRT 测速
:: "C:\Program Files\TensorRT-8.0.3.4\bin\trtexec.exe" --onnx=%job_name%.onnx --workspace=4096 --avgRuns=10 --shapes=input:1x3x640x640 --fp16
:: "C:\Program Files\TensorRT-8.0.3.4\bin\trtexec.exe" --onnx=%job_name%.onnx --workspace=4096 --avgRuns=10 --shapes=input:1x3x640x640 --fp32
echo 完成!
pause
以上脚本包含训练和测试部署等所有命令,我仅测试了训练和测试,如果还有更高的要求请按照官方文档进行配置,最终的结果会在/output显示出来,可能图上的标注会和你的标注无法对应上,这是正产现象,因为PaddleYOLO将coco数据集标注字典内置了,目前我还没找到修改的地方,完全不影响,因为结果是标注ID,如果需要可视化自行实现一个即可。
参考文章
站外引用 · 引用站外地址,不保证站点的可用性和安全性基于SeaShips数据集的yolov8训练教程blog.csdn.net@卧式纯绿 站外引用 · 引用站外地址,不保证站点的可用性和安全性基于YOLOv8的船舶目标检测系统(Python源码+Pyqt6界面+数据集)cloud.tencent.com@AI小怪兽 站外引用 · 引用站外地址,不保证站点的可用性和安全性PaddleYOLO:车牌检测yolov5aistudio.baidu.com@DDDDB 站外引用 · 引用站外地址,不保证站点的可用性和安全性快到没朋友的YOLO v3有了PaddlePaddle实现 | 代码+预训练模型百度大脑 - AI开放平台 站外引用 · 引用站外地址,不保证站点的可用性和安全性YOLO series of PaddlePaddle implementationgithub.com@PaddlePaddle声明
- 以上内容仅供学术研究和学习交流使用,如有侵权,请联系我进行删除处理。
- 若有任何问题或需要进一步讨论,请随时联系我的邮箱:01@liushen.fun。
每日一图
图片来自哲风壁纸
