YOLOv5实战:从零构建你的专属目标检测器

最近身边不少做嵌入式开发、机器人视觉的朋友都在问我同一个问题:有没有一个既快又准,还能快速上手的视觉检测方案?每次我都不假思索地推荐YOLOv5。这并非因为它是最前沿的学术成果,恰恰相反,它的魅力在于那份“开箱即用”的务实感。你不需要从零推导损失函数,也不必深究每一个卷积层的设计哲学,就能在几个小时内,让模型识别出你指定的物体——无论是生产线上的瑕疵品,还是自家花园里不同品种的花卉。

这份指南就是为你准备的,如果你正面临以下场景,那么它或许能成为你的“操作手册”:

  • 项目原型验证:需要快速验证某个视觉检测想法是否可行。
  • 特定领域应用:现有公开模型无法识别你的专属物品(如特定工业零件、珍稀动植物)。
  • 学习与入门:希望绕过繁杂的理论,直接通过实践理解目标检测的完整流程。

我们将完全从实战出发,绕过冗长的原理阐述,聚焦于“怎么做”。我会带你走过从搭建环境、准备数据、到训练调参、最终部署测试的每一个具体步骤,并分享一些只有踩过坑才知道的细节技巧。让我们直接开始。

1. 环境搭建与项目初始化

工欲善其事,必先利其器。YOLOv5对环境的要求相对友好,但一步到位地配置好,能避免后续无数奇怪的报错。我强烈建议使用Anaconda来创建独立的Python环境,这能完美解决不同项目间依赖包版本冲突的噩梦。

首先,确保你的机器拥有NVIDIA显卡并安装了合适版本的CUDA。这是利用GPU加速训练的前提。你可以通过以下命令检查:

nvidia-smi

这条命令会显示你的显卡型号和已安装的CUDA版本。记下CUDA版本(例如11.7),这决定了你需要安装的PyTorch版本。

接下来,我们创建并激活一个名为yolov5的虚拟环境(使用Python 3.8或3.9,这是兼容性最好的版本):

conda create -n yolov5 python=3.8
conda activate yolov5

环境激活后,安装PyTorch。请务必前往PyTorch官网,根据你的CUDA版本,选择对应的安装命令。例如,对于CUDA 11.7,命令可能如下:

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117

注意:直接使用pip install torch可能会安装仅支持CPU的版本,导致无法利用GPU。从官网获取命令是最稳妥的方式。

PyTorch安装成功后,克隆YOLOv5的官方仓库并安装其依赖:

git clone https://github.com/ultralytics/yolov5.git
cd yolov5
pip install -r requirements.txt

至此,核心环境就搭建完毕了。你可以运行一个简单的检测命令来验证一切是否正常:

python detect.py --source data/images/bus.jpg --weights yolov5s.pt

如果一切顺利,你会在runs/detect/exp目录下看到一张图片,上面的行人和车辆都被框了出来。恭喜,你的“武器库”已经就绪。

2. 数据准备:模型训练的基石

如果说算法是模型的大脑,那么数据就是供给大脑成长的营养。数据准备是整个流程中最需要耐心,也最能体现你领域知识的一环。YOLOv5支持的数据标注格式是YOLO格式,它是一种归一化的文本格式。

数据收集与标注 你的数据可以来自网络爬取、公开数据集,或者自己拍摄。对于初学者,我强烈建议从一个小型但高质量的自定义数据集开始,比如标注50-100张办公室里的“键盘”、“鼠标”、“水杯”。这能让你快速跑通流程,建立信心。

标注工具推荐使用LabelImg或Roboflow。LabelImg是本地开源工具,而Roboflow提供了在线标注、版本管理和数据增强的一站式服务。

  • LabelImg:设置简单,将输出格式选为YOLO,标注后每个图像会生成一个同名的.txt文件。
  • Roboflow:上传图片后,可以协作标注,并直接导出为YOLOv5格式的数据集压缩包,非常方便。

一个标准的YOLO格式标注文件(例如image001.txt)内容如下:

0 0.5 0.5 0.3 0.4
1 0.2 0.7 0.15 0.15

每一行代表一个物体,包含5个数值,以空格分隔:

  • 类别索引:对应data.yaml中names列表的序号(从0开始)。
  • 中心点x坐标:物体边界框中心点的x坐标,除以图片宽度进行归一化(范围0-1)。
  • 中心点y坐标:物体边界框中心点的y坐标,除以图片高度进行归一化。
  • 边界框宽度w:物体边界框的宽度,除以图片宽度进行归一化。
  • 边界框高度h:物体边界框的高度,除以图片高度进行归一化。

数据集组织结构与配置文件 YOLOv5要求数据集按特定结构组织。一个清晰的结构如下:

custom_dataset/
├── images/
│   ├── train/         # 训练集图片
│   │   ├── image1.jpg
│   │   └── ...
│   └── val/           # 验证集图片
│       ├── image100.jpg
│       └── ...
└── labels/
    ├── train/         # 训练集标签 (与images/train/图片一一对应)
    │   ├── image1.txt
    │   └── ...
    └── val/           # 验证集标签
        ├── image100.txt
        └── ...

接下来,你需要在YOLOv5项目的data/目录下(或你的数据集根目录)创建一个配置文件,例如custom_data.yaml。这个文件是连接你的数据和训练脚本的桥梁。

# custom_data.yaml
path: ../custom_dataset  # 数据集根目录
train: images/train      # 训练集路径(相对于path)
val: images/val          # 验证集路径(相对于path)

# 类别数量
nc: 3  # 例如,我们检测键盘、鼠标、水杯,共3类

# 类别名称列表
names: ['keyboard', 'mouse', 'cup']

提示:务必确保images和labels目录下的文件名(不含扩展名)一一对应。这是最常见的错误来源之一。可以使用简单的脚本检查是否有图片缺少标签,或反之。

3. 模型训练:参数调整与技巧

数据准备妥当后,激动人心的训练环节就开始了。YOLOv5提供了从轻量到重量的多个预训练模型,我们可以基于它们进行迁移学习,这能极大加快收敛速度并提升最终精度。

选择预训练模型与启动训练 YOLOv5主要提供以下几种模型,你可以根据对速度和精度的权衡进行选择:

模型尺寸 (像素)参数量 (百万)推理速度 (CPU/GPU)适用场景
YOLOv5n6401.9极快移动端、嵌入式设备,对速度要求极高
YOLOv5s6407.2很快入门首选,速度与精度平衡
YOLOv5m64021.2中等大多数桌面应用,精度显著提升
YOLOv5l64046.5较慢服务器端,追求高精度
YOLOv5x64086.7慢研究或对精度有极致要求的场景

对于我们的自定义数据集,从YOLOv5s开始是最佳选择。使用以下命令启动训练:

python train.py \
  --img 640 \                    # 训练图像尺寸
  --batch 16 \                   # 批次大小,根据GPU内存调整
  --epochs 100 \                 # 训练轮数
  --data data/custom_data.yaml \ # 上一步创建的数据配置文件
  --weights yolov5s.pt \         # 使用预训练的yolov5s权重
  --project runs/train \         # 训练结果保存目录
  --name exp1                    # 本次实验名称

运行后,训练脚本会自动下载yolov5s.pt权重(如果本地没有),然后开始训练。你会在终端看到实时的损失下降曲线和性能指标,同时在runs/train/exp1目录下生成一系列有用的结果文件,包括:

  • weights/best.pt:训练过程中在验证集上表现最好的模型权重。
  • weights/last.pt:最后一轮的模型权重。
  • 各种可视化图表:损失曲线、精度召回曲线、混淆矩阵等,用于分析模型表现。

关键超参数解析与调整 训练不是一蹴而就的,根据结果调整超参数是提升模型性能的关键。以下是几个最值得关注的参数:

  • --img:输入图像的尺寸。增大尺寸(如从640到1280)通常会提升检测小物体的能力,但会显著增加显存消耗和训练时间。对于远景小目标,尝试增大此值。
  • --batch:批次大小。在GPU显存允许的范围内,使用更大的批次通常能使训练更稳定,收敛更快。如果出现“CUDA out of memory”错误,请减小此值或--img尺寸。
  • --epochs:训练轮数。轮数不足会导致欠拟合(模型没学够),过多则可能导致过拟合(模型只记住了训练集)。观察验证集损失曲线,当其不再明显下降甚至开始上升时,就应考虑提前停止。
  • --hyp:指定超参数配置文件。YOLOv5自带一个data/hyps/hyp.scratch-low.yaml文件,里面定义了学习率、数据增强强度等大量超参数。对于小数据集,建议使用hyp.finetune.yaml(更保守的数据增强,防止过拟合)。你可以通过--hyp data/hyps/hyp.finetune.yaml来指定。

一个常见的调整策略是:先用默认参数训练一轮(例如50个epoch),观察results.png中的损失曲线。如果训练损失下降很慢,可以适当增大学习率(在hyp文件中修改lr0和lrf);如果验证集损失很早就开始上升,而训练损失还在下降,说明过拟合了,需要增强数据增强(如mosaic, mixup)或使用更保守的hyp.finetune.yaml配置。

4. 模型评估、优化与部署

训练完成后,我们得到了best.pt模型。但这远不是终点,我们需要客观地评估它,并可能进行优化,最后将其部署到实际应用中。

模型性能评估 YOLOv5在训练过程中已经生成了评估指标。我们重点关注以下几个:

  • mAP@0.5 (mean Average Precision):这是目标检测最核心的指标。它衡量模型在不同置信度阈值下,对所有类别的平均检测精度。值越高越好,通常达到0.8以上说明模型非常优秀。
  • Precision (精确率):模型预测为正的样本中,真正为正的比例。高精确率意味着模型“不错怪”。
  • Recall (召回率):所有真实为正的样本中,被模型正确找出的比例。高召回率意味着模型“不漏检”。

你可以使用val.py脚本在独立的测试集上(如果你有)进行更严谨的评估:

python val.py \
  --weights runs/train/exp1/weights/best.pt \
  --data data/custom_data.yaml \
  --img 640 \
  --task test  # 如果你在data.yaml中定义了test集路径

常见问题分析与优化 如果指标不理想,别灰心,我们可以有针对性地进行优化:

  1. 过拟合(训练集表现好,验证集差):

    • 增加数据:收集更多数据是最根本的方法。
    • 数据增强:在hyp配置文件中增强mosaic, mixup, hsv_h, hsv_s, hsv_v, translate, scale, shear等参数。YOLOv5默认的数据增强已经很强大。
    • 使用预训练权重:确保你使用了--weights yolov5s.pt,而不是从头训练。
    • 减少模型复杂度:如果数据量很少,可以尝试更小的模型(如YOLOv5n)。
    • 早停:根据验证集损失提前停止训练。
  2. 欠拟合(训练集和验证集表现都差):

    • 增加训练轮数:延长--epochs。
    • 减小正则化:在hyp配置文件中,尝试减小weight_decay,或增大box, cls, obj损失的权重系数。
    • 检查数据质量:标注是否正确、一致?类别定义是否清晰?
    • 增大模型:换用更大的预训练模型(如YOLOv5m)。
  3. 特定类别检测效果差:

    • 类别不平衡:检查数据集中各类别的图片数量是否悬殊。对于样本数少的类别,可以尝试对该类图片进行过采样,或在train.py中使用--cls_pw参数设置类别权重。
    • 标注质量:重点复查该类别标注的准确性和完整性。

模型部署与推理 模型最终要投入使用。YOLOv5提供了极其简便的推理脚本detect.py。你可以用它检测图片、视频、甚至实时摄像头流。

# 检测单张图片
python detect.py --weights runs/train/exp1/weights/best.pt --source path/to/your/image.jpg

# 检测视频
python detect.py --weights runs/train/exp1/weights/best.pt --source path/to/your/video.mp4

# 使用摄像头(设备索引0)
python detect.py --weights runs/train/exp1/weights/best.pt --source 0

# 保存结果
python detect.py --weights runs/train/exp1/weights/best.pt --source ... --save-txt --save-conf

--save-txt会保存检测框的坐标和类别信息为YOLO格式的文本文件,--save-conf会同时保存置信度。

对于生产环境,你可能需要将PyTorch模型导出为其他格式,以提升推理速度或适配不同平台。YOLOv5支持一键导出:

python export.py --weights runs/train/exp1/weights/best.pt --include onnx engine

这将导出ONNX格式(通用交换格式)和TensorRT引擎格式(用于NVIDIA GPU极致加速)。在Jetson等边缘设备上,TensorRT能带来数倍的性能提升。

最后,别忘了模型训练是一个迭代的过程。我的第一个自定义模型mAP只有0.3,通过反复检查数据、调整增强参数、清洗错误标注,最终提升到了0.85。每次训练后,多用detect.py在各种各样的场景图片上测试,直观地看它在哪里成功,在哪里失败。这些失败的案例,往往就是你下一轮数据收集和模型优化的方向。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐