YOLOv5训练自定义数据集全攻略
在计算机视觉的实际项目中,我们常常需要让模型识别特定场景中的目标——比如工厂流水线上的缺陷零件、停车场里的特定车型,或是实验室里某种生物样本。通用的目标检测模型(如COCO预训练模型)虽然强大,但面对这些“定制化”需求时往往力不从心。这时,基于YOLOv5训练一个专属的自定义数据集模型,就成了最实用、最高效的解决方案。
这套流程不仅要求你懂代码和参数,更考验对数据质量、标注规范与训练调优的整体把控能力。本文将带你从零开始,走完一条完整且可复现的实战路径,避开那些新手常踩的坑。
环境准备:稳扎稳打的第一步
任何深度学习项目的起点都是环境配置。对于YOLOv5来说,版本兼容性尤其关键——PyTorch太低跑不了新特性,太高又可能破坏原有依赖。别小看这一步,很多人卡住的根本原因就是环境没配好。
推荐组合如下:
- Python 3.9(兼容性最佳)
- PyTorch 1.13.1 + CUDA 11.7或PyTorch 2.0+ + CUDA 11.8
- 使用Conda创建独立环境,避免污染全局包
创建虚拟环境命令:
conda create -n yolov5 python=3.9 conda activate yolov5激活后务必验证GPU是否可用:
import torch print(torch.cuda.is_available()) # 应输出 True print(torch.__version__)如果返回False,请检查:
- 显卡驱动是否更新
- CUDA Toolkit 是否安装正确
- PyTorch 安装命令是否带了正确的cuXXX后缀
💡 经验提示:国内用户建议使用清华源或阿里云镜像加速后续依赖安装。
克隆代码库:获取官方实现
YOLOv5由 Ultralytics 团队维护,是目前社区最活跃、文档最完善的开源实现。不要自己造轮子,直接用它。
GitHub地址:https://github.com/ultralytics/yolov5
通过 Git 克隆(推荐):
git clone https://github.com/ultralytics/yolov5.git cd yolov5如果你网络不稳定,也可以点击页面上的 “Code” → “Download ZIP”,解压到本地即可。
⚠️ 注意:克隆完成后不要急着运行脚本,先确保依赖齐全。
配置开发环境:PyCharm 提升效率
虽然终端也能跑通全流程,但当你需要调试数据加载、修改模型结构或分析损失曲线时,PyCharm这类 IDE 的断点调试和变量查看功能会极大提升开发效率。
操作步骤:
- 打开 PyCharm → Open Project → 选择
yolov5文件夹 - 进入 Settings → Project → Python Interpreter
- 添加 Conda 环境,指向你创建的
yolov5环境下的 Python 解释器
(Windows 示例路径:C:\Users\YourName\anaconda3\envs\yolov5\python.exe)
接着安装必要依赖:
pip install -r requirements.txt国内加速命令:
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple安装完成后,尝试导入几个核心库:
import torch, yaml, numpy, matplotlib # 不报错即成功一旦这些基础模块都能正常加载,说明你的环境已经 ready。
数据组织:清晰结构决定成败
YOLOv5 对数据目录有明确要求。混乱的文件结构会导致训练脚本找不到图像或标签,引发各种“找不到文件”的错误。
标准目录结构如下:
datasets/ └── my_dataset/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/images/train/和images/val/分别存放训练集和验证集图片(支持.jpg,.png等常见格式)labels/train/和labels/val/存放对应的 YOLO 格式.txt标注文件- 图片名与标注文件名必须一一对应:
img001.jpg↔img001.txt
📌 建议:至少准备 500 张以上标注图像,否则容易过拟合;验证集占比建议为总数据量的 10%~20%。
标注格式转换:统一归一化坐标
YOLOv5 只接受一种输入格式:归一化的中心点宽高表示法(normalized xywh)。这意味着无论原始标注是 Pascal VOC 的 XML 还是 COCO 的 JSON,最终都得转成这种形式。
YOLO 格式详解
每个.txt文件包含多行,每行代表一个目标:
<class_id> <x_center> <y_center> <width> <height>其中:
- 所有坐标值都在[0, 1]范围内
-<class_id>从0开始编号
- 坐标基于图像宽高进行归一化
示例:
0 0.485 0.365 0.120 0.200 1 0.820 0.640 0.150 0.250表示两个目标:类别0(人),位于图像中心附近;类别1(车),位于右下角区域。
如何转换?
如果你用的是 LabelImg(输出XML)
写个简单脚本批量处理:
import xml.etree.ElementTree as ET import os def convert_xml_to_txt(xml_path, txt_path, class_mapping): tree = ET.parse(xml_path) root = tree.getroot() img_width = int(root.find('size/width').text) img_height = int(root.find('size/height').text) with open(txt_path, 'w') as f: for obj in root.findall('object'): cls_name = obj.find('name').text if cls_name not in class_mapping: continue cls_id = class_mapping[cls_name] bndbox = obj.find('bndbox') xmin = float(bndbox.find('xmin').text) ymin = float(bndbox.find('ymin').text) xmax = float(bndbox.find('xmax').text) ymax = float(bndbox.find('ymax').text) # 计算归一化坐标 x_c = ((xmin + xmax) / 2) / img_width y_c = ((ymin + ymax) / 2) / img_height w = (xmax - xmin) / img_width h = (ymax - ymin) / img_height f.write(f"{cls_id} {x_c:.6f} {y_c:.6f} {w:.6f} {h:.6f}\n")遍历整个annotations/目录调用此函数即可完成批量转换。
如果你已有 COCO JSON
可以用开源工具labelme2yolo或编写脚本提取annotations字段并转换边界框。
🔍 小技巧:Roboflow 平台支持一键格式转换,适合不想写代码的用户。
编写数据配置文件:连接数据与模型的桥梁
在yolov5/data/下新建一个 YAML 文件,例如my_dataset.yaml:
path: D:/projects/yolov5/datasets/my_dataset train: images/train val: images/val nc: 3 names: ['person', 'car', 'dog']关键点说明:
-path推荐使用绝对路径,避免相对路径导致读取失败
-nc是类别数量,必须准确填写
-names列表顺序要和你的标签 ID 完全一致(即person=0,car=1,dog=2)
这个文件的作用是在训练时告诉train.py:去哪找数据、有多少类、每类叫什么名字。
调整模型结构:选对规模事半功倍
YOLOv5 提供了多个尺度的模型,适配不同硬件和性能需求:
| 模型 | 特点 | 适用场景 |
|---|---|---|
yolov5s | 小模型,速度快 | 移动端、边缘设备 |
yolov5m | 中等精度/速度 | 多数通用任务 |
yolov5l | 大模型,高精度 | 服务器部署 |
yolov5x | 超大模型 | 极致精度追求 |
打开对应配置文件(如models/yolov5s.yaml),修改类别数:
nc: 3 # 改为你自己的类别数即使你使用预训练权重(如yolov5s.pt),也建议提前改掉nc,否则框架会在加载时自动调整最后一层,虽然能运行但会抛出警告。
💡 工程经验:小数据集优先考虑
yolov5s或yolov5m,配合迁移学习效果更好。
启动训练:让模型真正“学起来”
一切就绪后,就可以启动训练了。
方法一:命令行方式(推荐)
在项目根目录执行:
python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data data/my_dataset.yaml \ --cfg models/yolov5s.yaml \ --weights yolov5s.pt \ --name my_custom_run参数说明:
---img: 输入尺寸,默认640×640,显存不够可降为320或416
---batch: batch size,根据GPU显存调整(GTX 3060建议≤16)
---epochs: 训练轮数,一般设为100足够收敛
---data: 数据配置文件路径
---cfg: 模型结构文件
---weights: 初始化权重,yolov5s.pt包含ImageNet+COCO预训练知识
---name: 实验名称,结果保存在runs/train/{name}
方法二:PyCharm运行
在train.py的运行配置中添加上述参数,或者修改主函数入口:
if __name__ == '__main__': opt = parse_opt() opt.img = 640 opt.batch = 16 opt.epochs = 100 opt.data = 'data/my_dataset.yaml' opt.cfg = 'models/yolov5s.yaml' opt.weights = 'yolov5s.pt' opt.name = 'my_custom_run' main(opt)这样可以直接在IDE里调试和观察变量。
结果分析:看懂指标才能优化模型
训练结束后,结果保存在:
runs/train/my_custom_run/ ├── weights/ │ ├── best.pt ← mAP最高的模型 │ └── last.pt ← 最后一轮保存的模型 ├── results.png ← 损失和指标变化曲线 └── labels/ ← 预测框与真实框对比图重点关注以下几个指标:
| 指标 | 含义 |
|---|---|
mAP@0.5 | IoU阈值为0.5时的平均精度,反映整体检测能力 |
mAP@0.5:0.95 | 多IoU阈值下的综合表现,更严格 |
Precision | 查准率,越高说明误检越少 |
Recall | 查全率,越高说明漏检越少 |
理想情况是mAP@0.5持续上升,Precision和Recall平衡增长。如果出现震荡或下降,可能是学习率过高或数据噪声太大。
常见问题排查:快速定位故障
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
CUDA out of memory | 显存不足 | 减小batch或降低img尺寸 |
No labels found | 标注路径错误或无有效标签 | 检查labels/目录是否存在对应.txt文件 |
| 类别名称错乱 | names顺序与 label ID 不符 | 确保yaml文件中列表顺序正确 |
| Loss 爆炸或出现 NaN | 学习率过高或标注异常 | 使用--lr0 0.001降低初始学习率,检查标注框是否超出图像范围 |
| mAP 一直很低 | 数据量少、类别不平衡或增强过度 | 增加难例样本、关闭部分数据增强(如mosaic)、清洗脏数据 |
进阶技巧推荐
启用 TensorBoard 实时监控
bash tensorboard --logdir runs/train
可实时查看 loss、learning rate、PR 曲线等。使用混合精度训练提速
bash --amp
自动启用 FP16 半精度训练,节省显存并加快速度。冻结主干网络前几层(适合小数据集)
bash --freeze 10
冻结 Backbone 前10层,只训练检测头,防止过拟合。更换预训练权重来源
可下载官方发布的yolov5s6.pt等更大感受野版本,提升小目标检测能力。
YOLOv5 的魅力在于它的简洁与高效。从数据准备到模型部署,整个流程高度工程化,几乎没有冗余环节。只要你掌握了数据格式规范、配置文件写法和基本调参逻辑,就能快速迭代出可用的检测模型。
更重要的是,这套方法论可以迁移到 YOLOv8、YOLOv10 甚至其他检测框架中。掌握一次,受益长久。
完成训练后,不妨用detect.py做一次推理测试,看看模型在实际图像上的表现。下一步还可以导出 ONNX 模型,集成到生产系统中,真正实现“从训练到落地”的闭环。
每一次成功的训练,都是对细节的一次胜利。加油,下一个工业级AI应用,也许就出自你手。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考