第4章:YOLO系列与目标检测实战:YOLOv5/v8原理讲解,模型训练与部署到边缘设备

目标检测这块,YOLO系列绝对是绕不开的坎。我入行那会儿还是YOLOv3称霸,现在v5和v8已经成了工业界的主流选择。说实话,v5和v8虽然名字像,但骨子里差别不小。今天咱们就掰开揉碎,把原理讲透,再带你把模型训出来、部署到边缘设备上。

4.1 YOLOv5:经典中的经典

YOLOv5刚出来的时候,很多人质疑它是不是蹭热度。但用过的都知道,这玩意儿是真的稳。我个人习惯把它当作目标检测的“基准线”——新项目先拿v5跑一遍,心里就有底了。

4.1.1 网络结构:CSPDarknet + PANet

v5的主干网络用的是CSPDarknet。说白了,就是把残差块和CSP结构结合了一下。CSP(Cross Stage Partial)的核心思想是:把特征图分成两部分,一部分正常卷积,另一部分直接拼过来。这样做的好处是——计算量降了,梯度信息还能更好地流动。

核心组件一览:

  • Focus层:把输入图切成4份,拼成通道数4倍的特征图。我刚开始觉得这操作有点多余,后来发现它确实能减少信息丢失。
  • C3模块:v5里的核心构建块,3个卷积加CSP结构。比v3/v4的残差块更轻量。
  • SPP层:空间金字塔池化,用不同尺寸的池化核提取多尺度特征。嗯,这里要注意,池化核大小要跟特征图尺寸匹配,不然会出问题。

颈部网络用的是PANet(路径聚合网络)。它跟FPN的区别在于:FPN是自顶向下传语义,PANet再加一条自底向上的路径传位置信息。说白了,就是让大目标和小目标都能被照顾到。

4.1.2 损失函数:CIoU + 分类损失

v5的边界框回归损失用的是CIoU Loss。它比原始的IoU多了两个惩罚项:中心点距离和宽高比一致性。我在项目中遇到过一个问题:用GIoU训练时,某些长条形目标的框总是偏大。换成CIoU后,这个问题就解决了。

# CIoU Loss 核心计算逻辑
def ciou_loss(pred, target):
    # pred, target: [x, y, w, h]
    iou = bbox_iou(pred, target)
    center_dist = (pred[:, :2] - target[:, :2]).pow(2).sum(dim=1)
    enclose_diag = (enclose_w.pow(2) + enclose_h.pow(2))
    v = (4 / (torch.pi ** 2)) * (torch.atan(target_w/target_h) - torch.atan(pred_w/pred_h)).pow(2)
    alpha = v / (1 - iou + v)
    return 1 - iou + center_dist / enclose_diag + alpha * v

4.2 YOLOv8:v5的全面进化

v8是Ultralytics在2023年推出的。说实话,第一次看到v8的架构图,我第一反应是:“这不就是v5改改吗?”但仔细研究后发现,改动的地方都很关键。

4.2.1 核心改进点

改进项 v5的做法 v8的做法 我的评价
主干网络 CSPDarknet C2f模块(更密集的跨层连接) 梯度流动更顺畅了
检测头 耦合头(分类+回归一起) 解耦头(分类和回归分开) 收敛更快,精度更高
Anchor策略 预设Anchor Anchor-Free 省了调Anchor的麻烦
损失函数 CIoU + BCE DFL + VFL 对小目标更友好

你想想看,v8把检测头拆成两个独立的分支,分类和回归各干各的。这样做的好处是——两个任务的优化目标不同,硬绑在一起反而互相干扰。我曾经在v5上试过解耦头,精度确实涨了1-2个点。

4.2.2 DFL损失:让框更准

DFL(Distribution Focal Loss)是v8的一个亮点。它把边界框的回归问题变成了一个分布估计问题。说白了,就是不再直接预测框的位置,而是预测框位置的概率分布。

我的经验:DFL对遮挡场景特别有效。有一次做行人检测,人挤人的情况下,v5的框经常偏移,v8的框就稳得多。代价是推理时多了几步计算,但边缘设备上也能接受。

4.3 模型训练:从数据到权重

训练这部分,我踩过的坑比走过的路还多。下面直接给出一套我验证过的流程。

4.3.1 数据准备

数据集格式推荐用YOLO格式:每张图片对应一个txt文件,每行是“类别 x_center y_center width height”,坐标归一化到0-1。

# 数据集目录结构
dataset/
├── images/
│   ├── train/
│   └── val/
├── labels/
│   ├── train/
│   └── val/
└── data.yaml  # 配置文件

data.yaml的内容很简单:

train: ./images/train
val: ./images/val
nc: 2  # 类别数
names: ['car', 'pedestrian']

4.3.2 训练配置

我个人习惯用以下配置作为起点:

  • 输入尺寸:640x640(边缘设备建议用320或416)
  • Batch size:能多大就多大,但边缘设备训练时建议8-16
  • 学习率:0.01,配合余弦退火调度
  • Epochs:300,但早停法(patience=50)
  • 数据增强:Mosaic + MixUp + HSV抖动

避坑指南:我曾经在训练时把Mosaic增强开到1.0,结果模型对小目标完全失效。后来发现Mosaic比例太高会让小目标被切碎。建议Mosaic概率设为0.5-0.7。

4.3.3 训练命令

# YOLOv5
python train.py --data data.yaml --weights yolov5s.pt --batch-size 16 --epochs 300

# YOLOv8
yolo train model=yolov8s.pt data=data.yaml batch=16 epochs=300

训练过程中,重点关注三个指标:mAP@0.5、mAP@0.5:0.95、以及loss曲线。如果loss降不下去,先检查数据标注有没有问题。我遇到过好几次,训练半天loss不降,最后发现是标注框的坐标反了。

4.4 部署到边缘设备

边缘设备上跑模型,说白了就是“戴着镣铐跳舞”。算力有限,内存有限,还得保证实时性。

4.4.1 模型转换

最常用的部署格式是ONNX和TensorRT。以TensorRT为例:

# 导出ONNX
python export.py --weights best.pt --include onnx

# 转TensorRT(需要NVIDIA显卡)
trtexec --onnx=best.onnx --saveEngine=best.trt --fp16

这里要注意,FP16精度下,某些模型精度会掉1-2个点。如果任务对精度要求极高,可以考虑INT8量化,但需要校准数据集。

4.4.2 边缘设备选型

设备 算力 功耗 适合场景
Jetson Nano 472 GFLOPS 10W 入门级,适合v5n/v8n
Jetson Orin NX 70 TOPS 15W 主流选择,v5s/v8s流畅
RK3588 6 TOPS (NPU) 8W 国产方案,性价比高

我个人推荐Jetson Orin NX,性价比最高。如果预算有限,RK3588的NPU跑YOLOv5s也能到30fps以上。

4.4.3 推理优化技巧

  • 输入尺寸裁剪:640x640降到416x416,速度能翻倍,精度只掉1-2个点
  • Batch推理:边缘设备上batch=1最快,别想着用大batch
  • 异步处理:用双缓冲机制,一个线程采集图像,一个线程推理
  • 后处理优化:NMS用CUDA实现,别用CPU跑

实战经验:我在Jetson Nano上部署YOLOv5n,原始模型跑不到10fps。做了三件事后跑到了25fps:输入尺寸降到320、用FP16推理、NMS换成TensorRT内置的。嗯,这三板斧基本够用。

4.5 本章知识体系

下面这张图把YOLO系列的核心逻辑串起来了。从数据到训练,再到部署,每一步都有坑,但也都有解法。

YOLO系列目标检测实战知识体系 数据准备 标注格式转换 数据增强策略 模型选择 YOLOv5 vs YOLOv8 n/s/m/l/x 版本选择 模型训练 超参数调优 损失函数监控 模型转换 ONNX / TensorRT FP16 / INT8量化 边缘部署 Jetson / RK3588 推理优化技巧 性能评估 mAP / FPS / 内存 精度-速度权衡 迭代优化循环 核心要点 v5稳、v8准,选型看场景 | 训练看数据质量 | 部署看算力约束 没有最好的模型,只有最适合的模型

YOLOv5和v8的选择,说白了就是看你的场景。如果追求稳定、社区资源多,选v5准没错。如果追求极致精度、愿意折腾新特性,v8值得一试。我个人两个都在用——老项目用v5维护,新项目直接上v8。

最后说一句:模型训出来只是第一步,部署到边缘设备上跑起来才是真本事。别怕踩坑,每个坑都是经验。我当年在Jetson上折腾了整整一周才把第一个模型跑通,现在回想起来,那些坑反而让我对部署流程理解得更深。

可可精品资料库