YOLO------pytorch与paddle实现YOLO
本文将深入探讨YOLO目标检测的理论基础,并通过PyTorch和PaddlePaddle两个深度学习框架来展示如何实现基础的YOLO模型。我们将首先介绍YOLO的基本概念,这些理论基础是理解和实现YOLO网络的基础。通过PyTorch和PaddlePaddle的代码示例,我们将展示如何设计、训练和评估一个YOLO目标检测模型,从而让读者能够直观地理解并掌握这两种框架在计算机视觉问题中的应用。
YOLO网络简介
论文地址(You Only Look Once: Unified, Real-Time Object Detection):https://arxiv.org/abs/1506.02640
人类只需一瞥图像,就能立刻知道图像中有什么物体、它们在哪里以及它们如何相互作用。人类的视觉系统既快速又准确,使我们能够在几乎无需有意识思考的情况下执行复杂的任务,比如驾驶。快速、准确的目标检测算法将使计算机能够在没有专门传感器的情况下驾驶汽车,使辅助设备能够向人类用户传达实时场景信息,并释放通用、响应迅速的机器人系统的潜力。
之前的一些目标检测方法,如R-CNN,使用区域提议方法首先在图像中生成潜在的边界框,然后在这些提议的框上运行分类器。分类后,使用后处理来细化边界框,消除重复的检测,并根据场景中的其他物体对框进行重新评分。这些复杂的流程是缓慢的,并且难以优化,因为每个单独的组件都必须单独训练。
YOLO将目标检测重新定义为一个单一的回归问题,直接从图像像素到边界框坐标和类别概率。使用YOLO系统,只需看一次(YOLO)图像,就可以预测存在哪些物体以及它们的位置。
YOLO令人耳目一新地简单,如下图。一个单一的卷积网络同时预测多个边界框和这些框的类别概率。
YOLO在全图像上进行训练,并直接优化检测性能。与传统的目标检测方法相比,这种统一的模型具有多种优势:
首先,YOLO非常快。由于YOLO将检测定义为回归问题,因此不需要复杂的流程。只需在测试时在新图像上运行YOLO网络来预测检测。YOLO基础网络在Titan X GPU上以每秒45帧的速度运行,无需批处理,而快速版本则以超过150 fps的速度运行。这意味着YOLO可以以小于25毫秒的延迟实时处理流媒体视频。此外,YOLO的平均精度是其他实时系统的两倍以上。有关YOLO的系统在网络摄像头上实时运行的演示,请参阅YOLO项目网页:https://docs.ultralytics.com/
其次,YOLO在做出预测时会全局考虑图像。与基于滑动窗口和区域提议的技术不同,YOLO在训练和测试期间都会看到整个图像,因此它隐式地编码了关于类别及其外观的上下文信息。Fast R-CNN是一种顶级的检测方法,它错误地将图像中的背景块视为物体,因为它无法看到更大的上下文。与Fast R-CNN相比,YOLO产生的背景错误不到其一半。
第三,YOLO学习了物体的可推广表示。在自然图像上进行训练并在艺术品上进行测试时,YOLO的性能远超DPM和R-CNN等顶级检测方法。由于YOLO具有高度可推广性,因此在应用于新领域或意外输入时,它不太可能崩溃。
YOLO在准确性方面仍然落后于最先进的检测系统。虽然它可以快速识别图像中的物体,但难以精确定位某些物体,尤其是小物体。
YOLO将输入图像划分为一个 S × S S \times S S×S的网格。如果一个目标的中心落入一个网格单元,那么该网格单元负责检测该目标。
每个网格单元预测 B B B个边界框和这些框的置信度得分。这些置信度得分反映了模型对于框内包含目标的信心,以及它认为自己预测的框的准确度。形式上,置信度定义为 P r ( O b j e c t ) ∗ I O U t r u t h p r e d Pr(Object) * IOU^{pred}_{truth} Pr(Object)∗IOUtruthpred。如果该网格单元内不存在目标,则置信度得分应为零。否则,我们希望置信度得分等于预测框与真实框之间的交并比(IOU)。
每个边界框包含5个预测值: x x x、 y y y、 w w w、 h h h和置信度。其中, ( x , y ) (x, y) (x,y)坐标表示边界框相对于网格单元边界的中心位置。宽度 w w w和高度 h h h是相对于整个图像预测的。最后,置信度预测表示预测框与任何真实框之间的IOU。
每个网格单元还预测 C C C个条件类别概率, P r ( C l a s s i ∣ O b j e c t ) Pr(Class_i|Object) Pr(Classi∣Object)。这些概率是在网格单元包含目标的条件下得出的。每个网格单元只预测一组类别概率,而不管边界框 B B B的数量。
在测试时,网络将条件类别概率和单个边界框的置信度预测相乘,即:
P r ( C l a s s i ∣ O b j e c t ) ∗ P r ( O b j e c t ) ∗ I O U t r u t h p r e d = P r ( C l a s s i ) ∗ I O U t r u t h p r e d Pr(Class_i|Object) * Pr(Object) * IOU_{truth_{pred}} = Pr(Class_i) * IOU^{pred}_{truth} Pr(Classi∣Object)∗Pr(Object)∗IOUtruthpred=Pr(Classi)∗IOUtruthpred
从而得到每个边界框的特定类别置信度得分。这些得分既编码了该类别出现在边界框中的概率,也编码了预测边界框与目标的匹配程度。
YOLO将检测建模为一个回归问题。它将图像划分为一个S×S的网格,并为每个网格单元预测B个边界框、这些边界框的置信度以及C类概率。这些预测被编码为一个S×S×(B∗5+C)的张量。
YOLO 发展历史
YOLO模型于2015年推出,因其高速度和准确性而迅速受到欢迎。由华盛顿大学的Joseph Redmon和Ali Farhadi开发。https://arxiv.org/pdf/1506.02640
2016年发布的YOLOv2通过引入批量归一化、锚框(anchor boxes)和维度聚类(dimension clusters)对原始模型进行了改进。https://arxiv.org/pdf/1612.08242
2018年推出的YOLOv3通过使用更高效的主干网络、多个锚点和空间金字塔池化(spatial pyramid pooling),进一步提升了模型的性能。https://pjreddie.com/media/files/papers/YOLOv3.pdf
2020年发布的YOLOv4引入了诸如Mosaic数据增强、新的无锚点检测头(anchor-free detection head)和新的损失函数等创新点。https://arxiv.org/pdf/2004.10934
YOLOv5进一步提升了模型的性能,并添加了新的特性,如超参数优化、集成实验跟踪和自动导出到流行的导出格式。https://github.com/ultralytics/yolov5
2022年,美团开源了YOLOv6,该版本目前已在该公司的许多自主配送机器人中使用。https://github.com/meituan/YOLOv6
YOLOv7在COCO关键点数据集上增加了额外的任务,如姿态估计。https://github.com/WongKinYiu/yolov7
YOLOv8是Ultralytics推出的YOLO最新版本。作为一个前沿的、最先进的(SOTA)模型,YOLOv8借鉴了之前版本的成功经验,引入了新的特性和改进,以提高性能、灵活性和效率。YOLOv8支持全系列的视觉AI任务,包括检测、分割、姿态估计、跟踪和分类。这种多功能性使用户能够在不同的应用和领域中利用YOLOv8的能力。https://github.com/ultralytics/ultralytics
YOLOv9引入了创新的方法,如可编程梯度信息(PGI)和广义高效层聚合网络(GELAN)。https://docs.ultralytics.com/models/yolov9/
YOLOv10是由清华大学的研究人员使用Ultralytics Python包创建的。这个版本通过引入一个端到端的头部结构,消除了非极大值抑制(NMS)的需求,从而提供了实时目标检测的进步。https://docs.ultralytics.com/models/yolov10/
Pytorch实现YOLO模型
YOLO安装
可参考YOLO官网快速入门:https://docs.ultralytics.com/zh/quickstart/#install-ultralytics ,进行YOLO的安装。
从python库中进行安装( https://pypi.org/project/ultralytics/):
python
# Install the ultralytics package from PyPI
pip install ultralytics
直接从gitHub仓库进行安装(https://github.com/ultralytics/ultralytics):
python
# Install the ultralytics package from GitHub
pip install git+https://github.com/ultralytics/ultralytics.git@main
训练YOLO网络
官网介绍文档:https://docs.ultralytics.com/zh/modes/train/
接下来我们介绍如何使用自己的数据集进行网络训练过程。该过程可以参照作者的另一篇文章:图像识别------------玩转YOLO。
我们使用数据集coco128,下载地址:coco128数据集,coco128数据集下载,该数据集中有文件夹images原始图像,labels标签,我们通过设计函数,将data数据集中数据进行适当的调整,转化为ultralytics HUB标准的数据集格式。
HUB Datasets制作可查看官网:https://docs.ultralytics.com/hub/datasets/
python
import os
import shutil
import random
from pathlib import Path
def check_names_match(image_files, label_files):
'''
检查图片文件名与标签文件名是否匹配
如果匹配,则返回True,否则返回False
'''
for image_file, label_file in zip(image_files, label_files):
if image_file.split('.')[0] != label_file.split('.')[0]:
# 在这里添加删除不匹配文件的代码
image_files.remove(image_file)
label_files.remove(label_file)
while len(image_files) != len(label_files):
if len(image_files) > len(label_files):
# 删除多余的图片文件
image_files.pop()
else:
# 删除多余的标签文件
label_files.pop()
return True
def split_data(image_dir, label_dir, output_dir, train_ratio=0.8, val_ratio=0.1, test_ratio=0.1):
"""
将数据集中的图片和标签按照指定比例分割成训练、验证和测试集,并创建相应的文件夹结构。
参数:
image_dir (str): 原始图片所在的文件夹路径。
label_dir (str): 原始标签所在的文件夹路径。
output_dir (str): 输出文件夹的路径,用于存放分割后的数据。
train_ratio (float): 训练集所占的比例,默认为0.8。
val_ratio (float): 验证集所占的比例,默认为0.1。
test_ratio (float): 测试集所占的比例,默认为0.1。
"""
# 确保比例总和为1
assert train_ratio + val_ratio + test_ratio == 1.0, "Ratios must sum up to 1"
# 创建输出目录结构
Path(output_dir).mkdir(parents=True, exist_ok=True)
output_dir = Path(output_dir)
for subset in ['train', 'val', 'test']:
# 使用Path对象的joinpath方法来连接路径,并创建目录
(output_dir.joinpath('images', subset)).mkdir(parents=True, exist_ok=True)
(output_dir.joinpath('labels', subset)).mkdir(parents=True, exist_ok=True)
# 获取所有图片和标签的文件名
image_files = sorted(os.listdir(image_dir))
label_files = sorted(os.listdir(label_dir))
check_names_match(image_files, label_files)
# 打乱文件列表
combined = list(zip(image_files, label_files))
random.shuffle(combined)
image_files[:], label_files[:] = zip(*combined)
# 根据比例分割数据集
num_files = len(image_files)
train_end = int(num_files * train_ratio)
val_end = train_end + int(num_files * val_ratio)
# 复制文件到对应的文件夹
for i, (img_file, lbl_file) in enumerate(zip(image_files, label_files)):
if i < train_end:
subset = 'train'
elif i < val_end:
subset = 'val'
else:
subset = 'test'
shutil.copy(os.path.join(image_dir, img_file), os.path.join(output_dir, 'images', subset, img_file))
shutil.copy(os.path.join(label_dir, lbl_file), os.path.join(output_dir, 'labels', subset, lbl_file))
import yaml
def generate_yaml_file(output_dir, dataset_name):
'''
根据数据集生成yaml文件
'''
data = {
"train": f"images/train",
"val": f"images/val",
"test": f"images/test",
"nc": 0, # 类别数量,需要根据实际情况修改
"names": [] # 类别名称列表,需要根据实际情况修改
}
# 读取类别名称
label_dir = f"{output_dir}/labels"
for subset in ["train", "val", "test"]:
try:
label_files = os.listdir(os.path.join(label_dir, subset))
for label_file in label_files:
with open(os.path.join(label_dir, subset, label_file), "r") as f:
lines = f.readlines()
for line in lines:
class_name = line.split(" ")[0]
if class_name not in data["names"]:
data["names"].append(class_name)
data["nc"] += 1
except FileNotFoundError:
data.pop(subset)
continue
# 写入yaml文件
with open(f"{output_dir}/{dataset_name}.yaml", "w") as f:
yaml.dump(data, f)
python
# 使用,我们将data中数据整理到data_sorted文件夹中
path_img = 'data\coco128\images'
path_label = 'data\coco128\labels'
path_out = 'data\coco128_sorted'
split_data(path_img, path_label, path_out)
generate_yaml_file(path_out, 'coco128')
注意,此时生成的COCO128.yaml文件只是一个基本的yaml,里边信息并不能反映出真实的图片信息,读者可以对文件内容进行修改,可参考yolo官网的yaml文件格式:
java
# Ultralytics YOLO 🚀, AGPL-3.0 license
# COCO8 dataset (first 8 images from COCO train2017) by Ultralytics
# Documentation: https://docs.ultralytics.com/datasets/detect/coco8/
# Example usage: yolo train data=coco8.yaml
# parent
# ├── ultralytics
# └── datasets
# └── coco8 ← downloads here (1 MB)
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: ../datasets/coco8 # dataset root dir
train: images/train # train images (relative to 'path') 4 images
val: images/val # val images (relative to 'path') 4 images
test: # test images (optional)
# Classes
names:
0: person
1: bicycle
2: car
3: motorcycle
4: airplane
5: bus
6: train
7: truck
8: boat
9: traffic light
10: fire hydrant
11: stop sign
12: parking meter
13: bench
14: bird
15: cat
16: dog
17: horse
18: sheep
19: cow
20: elephant
21: bear
22: zebra
23: giraffe
24: backpack
25: umbrella
26: handbag
27: tie
28: suitcase
29: frisbee
30: skis
31: snowboard
32: sports ball
33: kite
34: baseball bat
35: baseball glove
36: skateboard
37: surfboard
38: tennis racket
39: bottle
40: wine glass
41: cup
42: fork
43: knife
44: spoon
45: bowl
46: banana
47: apple
48: sandwich
49: orange
50: broccoli
51: carrot
52: hot dog
53: pizza
54: donut
55: cake
56: chair
57: couch
58: potted plant
59: bed
60: dining table
61: toilet
62: tv
63: laptop
64: mouse
65: remote
66: keyboard
67: cell phone
68: microwave
69: oven
70: toaster
71: sink
72: refrigerator
73: book
74: clock
75: vase
76: scissors
77: teddy bear
78: hair drier
79: toothbrush
现在我们加载yolo模型并进行训练:
选择模型
登入网站ultralytics hub,在Models中可以看到很多模型,选择合适的模型进行训练,例如yolov8m.pt,下载到本地,并加载模型即可:
导出模型后,我们只需将模型文件yolov8m.pt放入项目文件夹中,并加载模型即可。也可通过官网示例进行训练:https://docs.ultralytics.com/zh/modes/train/
python
from ultralytics import YOLO
# Load a model
model = YOLO("yolov8m.pt")
训练模型并结果分析
python
# Train the model
results = model.train(data="data\coco128_sorted\coco128.yaml", epochs=100)
python
Ultralytics YOLOv8.2.74 🚀 Python-3.10.12 torch-2.0.1+cu118 CUDA:0 (NVIDIA GeForce RTX 4090, 24217MiB)
[34m[1mengine/trainer: [0mtask=detect, mode=train, model=yolov8m.pt, data=/home/featurize/data/datasets/data/coco128_sorted/coco128.yaml, epochs=100, time=None, patience=100, batch=16, imgsz=640, save=True, save_period=-1, cache=False, device=None, workers=8, project=None, name=train, exist_ok=False, pretrained=True, optimizer=auto, verbose=True, seed=0, deterministic=True, single_cls=False, rect=False, cos_lr=False, close_mosaic=10, resume=False, amp=True, fraction=1.0, profile=False, freeze=None, multi_scale=False, overlap_mask=True, mask_ratio=4, dropout=0.0, val=True, split=val, save_json=False, save_hybrid=False, conf=None, iou=0.7, max_det=300, half=False, dnn=False, plots=True, source=None, vid_stride=1, stream_buffer=False, visualize=False, augment=False, agnostic_nms=False, classes=None, retina_masks=False, embed=None, show=False, save_frames=False, save_txt=False, save_conf=False, save_crop=False, show_labels=True, show_conf=True, show_boxes=True, line_width=None, format=torchscript, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=None, workspace=4, nms=False, lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=7.5, cls=0.5, dfl=1.5, pose=12.0, kobj=1.0, label_smoothing=0.0, nbs=64, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, bgr=0.0, mosaic=1.0, mixup=0.0, copy_paste=0.0, auto_augment=randaugment, erasing=0.4, crop_fraction=1.0, cfg=None, tracker=botsort.yaml, save_dir=runs/detect/train
from n params module arguments
0 -1 1 1392 ultralytics.nn.modules.conv.Conv [3, 48, 3, 2]
1 -1 1 41664 ultralytics.nn.modules.conv.Conv [48, 96, 3, 2]
2 -1 2 111360 ultralytics.nn.modules.block.C2f [96, 96, 2, True]
3 -1 1 166272 ultralytics.nn.modules.conv.Conv [96, 192, 3, 2]
4 -1 4 813312 ultralytics.nn.modules.block.C2f [192, 192, 4, True]
5 -1 1 664320 ultralytics.nn.modules.conv.Conv [192, 384, 3, 2]
6 -1 4 3248640 ultralytics.nn.modules.block.C2f [384, 384, 4, True]
7 -1 1 1991808 ultralytics.nn.modules.conv.Conv [384, 576, 3, 2]
8 -1 2 3985920 ultralytics.nn.modules.block.C2f [576, 576, 2, True]
9 -1 1 831168 ultralytics.nn.modules.block.SPPF [576, 576, 5]
10 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']
11 [-1, 6] 1 0 ultralytics.nn.modules.conv.Concat [1]
12 -1 2 1993728 ultralytics.nn.modules.block.C2f [960, 384, 2]
13 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']
14 [-1, 4] 1 0 ultralytics.nn.modules.conv.Concat [1]
15 -1 2 517632 ultralytics.nn.modules.block.C2f [576, 192, 2]
16 -1 1 332160 ultralytics.nn.modules.conv.Conv [192, 192, 3, 2]
17 [-1, 12] 1 0 ultralytics.nn.modules.conv.Concat [1]
18 -1 2 1846272 ultralytics.nn.modules.block.C2f [576, 384, 2]
19 -1 1 1327872 ultralytics.nn.modules.conv.Conv [384, 384, 3, 2]
20 [-1, 9] 1 0 ultralytics.nn.modules.conv.Concat [1]
21 -1 2 4207104 ultralytics.nn.modules.block.C2f [960, 576, 2]
22 [15, 18, 21] 1 3822016 ultralytics.nn.modules.head.Detect [80, [192, 384, 576]]
Model summary: 295 layers, 25,902,640 parameters, 25,902,624 gradients, 79.3 GFLOPs
Transferred 475/475 items from pretrained weights
[34m[1mTensorBoard: [0mStart with 'tensorboard --logdir runs/detect/train', view at http://localhost:6006/
Freezing layer 'model.22.dfl.conv.weight'
[34m[1mAMP: [0mrunning Automatic Mixed Precision (AMP) checks with YOLOv8n...
[34m[1mAMP: [0mchecks passed ✅
[34m[1mtrain: [0mScanning /home/featurize/data/datasets/data/coco128_sorted/labels/train.cache... 59 images, 24 backgrounds, 0 corrupt: 100%|██████████| 83/83 [00:00<?, ?it/s]
[34m[1mval: [0mScanning /home/featurize/data/datasets/data/coco128_sorted/labels/val.cache... 8 images, 8 backgrounds, 0 corrupt: 100%|██████████| 16/16 [00:00<?, ?it/s]
Plotting labels to runs/detect/train/labels.jpg...
[34m[1moptimizer:[0m 'optimizer=auto' found, ignoring 'lr0=0.01' and 'momentum=0.937' and determining best 'optimizer', 'lr0' and 'momentum' automatically...
[34m[1moptimizer:[0m AdamW(lr=0.000119, momentum=0.9) with parameter groups 77 weight(decay=0.0), 84 weight(decay=0.0005), 83 bias(decay=0.0)
[34m[1mTensorBoard: [0mmodel graph visualization added ✅
Image sizes 640 train, 640 val
Using 8 dataloader workers
Logging results to [1mruns/detect/train[0m
Starting training for 100 epochs...
Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
1/100 7.65G 0.7807 0.8657 1.074 2 640: 100%|██████████| 6/6 [00:04<00:00, 1.30it/s]
Class Images Instances Box(P R mAP50 mAP50-95): 100%|██████████| 1/1 [00:00<00:00, 16.72it/s] all 16 35 0.741 0.865 0.864 0.723
Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
2/100 7.6G 0.7839 0.6583 1.04 18 640: 100%|██████████| 6/6 [00:00<00:00, 8.44it/s]
Class Images Instances Box(P R mAP50 mAP50-95): 100%|██████████| 1/1 [00:00<00:00, 17.89it/s] all 16 35 0.765 0.891 0.88 0.738
...(此处省略训练过程)
Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
100/100 7.66G 0.4719 0.3212 0.8571 13 640: 100%|██████████| 6/6 [00:00<00:00, 9.82it/s]
Class Images Instances Box(P R mAP50 mAP50-95): 100%|██████████| 1/1 [00:00<00:00, 18.14it/s] all 16 35 0.901 0.98 0.952 0.894
100 epochs completed in 0.050 hours.
Optimizer stripped from runs/detect/train/weights/last.pt, 52.1MB
Optimizer stripped from runs/detect/train/weights/best.pt, 52.1MB
Validating runs/detect/train/weights/best.pt...
Ultralytics YOLOv8.2.74 🚀 Python-3.10.12 torch-2.0.1+cu118 CUDA:0 (NVIDIA GeForce RTX 4090, 24217MiB)
Model summary (fused): 218 layers, 25,886,080 parameters, 0 gradients, 78.9 GFLOPs
Class Images Instances Box(P R mAP50 mAP50-95): 100%|██████████| 1/1 [00:00<00:00, 12.67it/s]
all 16 35 0.906 0.981 0.952 0.908
person 2 8 0.639 0.667 0.724 0.48
car 1 1 0.484 1 0.497 0.497
motorcycle 1 2 0.96 1 0.995 0.995
truck 1 1 0.937 1 0.995 0.995
bench 1 2 0.984 1 0.995 0.995
dog 1 1 0.926 1 0.995 0.895
elephant 1 2 0.962 1 0.995 0.995
fork 1 1 0.92 1 0.995 0.995
bowl 2 4 0.989 1 0.995 0.973
orange 1 4 0.992 1 0.995 0.961
broccoli 1 1 0.914 1 0.995 0.995
cake 1 1 0.921 1 0.995 0.995
potted plant 1 1 0.953 1 0.995 0.895
oven 1 1 0.927 1 0.995 0.995
sink 1 1 0.949 1 0.995 0.995
refrigerator 1 1 0.92 1 0.995 0.995
clock 2 2 1 0.989 0.995 0.704
vase 1 1 0.935 1 0.995 0.995
Speed: 0.1ms preprocess, 1.6ms inference, 0.0ms loss, 0.5ms postprocess per image
Results saved to [1mruns/detect/train[0m
从上方训练过程可以简单看出模型的训练效果及训练时的参数,模型所有的训练结果都将保存到训练时生成的文件夹runs中,主要包括以下部分,各部分具体内容可见博客:https://blog.csdn.net/java1314777/article/details/134154676 :
- runs/detect/train/weights/best.pt:训练过程中表现最好的模型权重文件
- runs/detect/train/weights/last.pt:训练过程中最后一次的模型权重文件
- runs/detect/train/results.csv:训练过程中每次epoch的评估结果,包括每一轮的 train/box_loss(训练时边界框损失), train/cls_loss(训练时分类损失), train/dfl_loss(训练时Distribution Focal Loss), metrics/precision(B)(预测正确的正样本比例), metrics/recall(B)(模型能够找出所有真实正样本比例), metrics/mAP50(B)(在50%的IOU阈值下MAP值), metrics/mAP50-95(B)(在50%~95%的IOU下MAP值取平均), val/box_loss(验证时边界框损失), val/cls_loss(验证时分类损失), val/dfl_loss(验证时Distribution Focal Loss)
- runs/detect/train/args.yaml:训练过程中使用的参数
- runs/detect/train/confusion_matrix.png: 混淆矩阵
- runs/detect/train/confusion_matrix_normalized.png: 归一化化混淆矩阵
- runs/detect/train/PR_curve.png: 精确率-召回率曲线
- runs/detect/train/P_curve.png: 精确率曲线
- runs/detect/train/R_curve.png: 召回率曲线
- runs/detect/train/F1-curve.png: F1曲线
- runs/detect/train/results.png: 训练结果可视化
- runs/detect/train/labels.jpg: 目标的类别和边界框信息
- runs/detect/train/labels_correlogram.jpg: 预测标签之间的相关性
PaddlePaddle实现YOLO
项目位置: https://github.com/PaddlePaddle/PaddleYOLO
项目Gitee位置: https://gitee.com/paddlepaddle/PaddleDetection
PaddleYOLO安装
安装说明:https://github.com/PaddlePaddle/PaddleYOLO/blob/develop/docs/tutorials/INSTALL_cn.md
首先需要安装paddlepaddle:
python
# CUDA(GPU版本CUDA)
python -m pip install paddlepaddle-gpu==2.3.2 -i https://mirror.baidu.com/pypi/simple
# CPU(CPU版本)
python -m pip install paddlepaddle==2.3.2 -i https://mirror.baidu.com/pypi/simple
python
import paddle
print("paddle version:",paddle.__version__)
paddle version: 2.5.2
安装PaddleDetection:
python
# 克隆PaddleDetection仓库
cd <path/to/clone/PaddleDetection>
git clone https://github.com/PaddlePaddle/PaddleDetection.git
# 安装其他依赖
cd PaddleDetection
pip install -r requirements.txt
# 编译安装paddledet
python setup.py install
训练YOLO模型
读者可结合paddleYOLO官网教程进行YOLO目标检测模型的训练部署:https://gitee.com/paddlepaddle/PaddleDetection/tree/release/2.7/docs/tutorials
准备数据集:
PaddleDetection默认支持COCO和Pascal VOC 和WIDER-FACE 数据源。准备数据集教程:https://gitee.com/paddlepaddle/PaddleDetection/blob/release/2.7/docs/tutorials/data/PrepareDetDataSet.md
同时还支持自定义数据源,包括:
- (1) 自定义数据转换成VOC数据;
- (2) 自定义数据转换成COCO数据;
- (3) 自定义新的数据源,增加自定义的reader。
我们下载一下VOC数据集:
首先在PaddleDetection文件夹内打开终端,或者执行:
shell
cd PaddleDetection/
然后执行:
shell
python dataset/roadsign_voc/download_roadsign_voc.py
如果成功运行的话,即可在PaddleDetection/dataset中看到roadsign_voc文件夹:
├── download_roadsign_voc.py
├── annotations
│ ├── road0.xml
│ ├── road1.xml
│ | ...
├── images
│ ├── road0.png
│ ├── road1.png
│ | ...
├── label_list.txt
├── train.txt
├── valid.txt
训练
在PaddleDetection中打开文件configs/yolov3/yolov3_mobilenet_v1_roadsign.yml,可以看到该文件已经配置好了下载数据集训练和测试的参数:
_BASE_: [
'../datasets/roadsign_voc.yml',
'../runtime.yml',
'_base_/optimizer_40e.yml',
'_base_/yolov3_mobilenet_v1.yml',
'_base_/yolov3_reader.yml',
]
pretrain_weights: https://paddledet.bj.bcebos.com/models/yolov3_mobilenet_v1_270e_coco.pdparams
weights: output/yolov3_mobilenet_v1_roadsign/model_final
YOLOv3Loss:
ignore_thresh: 0.7
label_smooth: true
命令行执行命令:
export CUDA_VISIBLE_DEVICES=0 #windows和Mac下不需要执行该命令
python tools/train.py -c configs/yolov3/yolov3_mobilenet_v1_roadsign.yml
训练好之后在output文件夹中即可看到训练过程中产生的所有模型参数,让我们把最终的模型参数加载一下进行预测.
在命令行执行:
shell
python tools/infer.py -c configs/yolov3/yolov3_mobilenet_v1_roadsign.yml \
--infer_img=demo/road554.png \
--output_dir=infer_output/ \
--draw_threshold=0.5 \
-o weights=output/model_final \
--use_vdl=True
在PaddleDetection/infer_output/road554.png中即可看到图像的目标检测结果: