YOLOv5训练自定义数据集完整指南
在计算机视觉的实际项目中,目标检测是应用最广泛的任务之一。无论是工业质检中的缺陷识别、交通监控中的车辆分类,还是安防系统中的行人追踪,都需要一个既快又准的模型来支撑实时决策。而说到高效部署与高精度兼顾的解决方案,YOLOv5几乎成了工程师们的首选。
它不像某些学术模型那样“纸上谈兵”——虽然指标亮眼却难以落地。相反,YOLOv5 从设计之初就强调工程实用性:简洁的代码结构、端到端的训练流程、开箱即用的推理接口,再加上 Ultralytics 团队持续维护和优化,让它迅速成为工业界事实上的标准工具。
如果你正打算用 YOLOv5 训练自己的数据集,但被环境配置、标注格式转换或路径问题卡住,别担心。本文将带你一步步走完从零开始的全过程,不跳步骤,不留坑点。
环境准备:让一切运行起来
动手前先确保你的开发环境已经就绪。这里推荐使用 Conda 管理 Python 环境,既能避免依赖冲突,也方便切换不同项目的运行时。
# 创建独立环境(建议 Python 3.9) conda create -n yolov5 python=3.9 conda activate yolov5 # 安装 PyTorch + CUDA 支持(以 11.8 为例) conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia安装完成后务必验证 GPU 是否可用:
import torch print(torch.cuda.is_available()) # 应输出 True如果返回False,请检查:
- 显卡驱动版本是否支持当前 CUDA
- 是否正确安装了cudatoolkit
- PyTorch 是否为 GPU 版本
确认无误后,再继续后续操作,否则训练速度会慢上几倍。
获取代码:稳定分支更可靠
YOLOv5 的官方仓库托管在 GitHub 上:
👉 https://github.com/ultralytics/yolov5
推荐通过 Git 克隆,并锁定一个稳定版本,比如v6.2或v7.0,而不是直接使用主干最新提交。这样可以避免因 API 变动导致脚本报错。
git clone https://github.com/ultralytics/yolov5.git cd yolov5 git checkout v6.2 # 切换到指定版本为什么不建议下载 ZIP?因为缺少.git目录会导致部分功能异常(如自动记录 commit ID),而且不利于后期更新。
IDE 集成:PyCharm 中的项目导入
打开 PyCharm,选择Open Project,定位到yolov5文件夹。
进入项目后,第一件事就是设置正确的解释器:
File → Settings → Project → Python Interpreter → Add → Existing Environment
选择你刚刚创建的 conda 环境路径,例如:~/anaconda3/envs/yolov5/bin/python
接着,在终端执行依赖安装:
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple国内镜像源能显著提升下载速度,尤其是torch这类大包。
安装完成后,跑个简单测试看看基础功能是否正常:
python detect.py --source data/images程序会加载默认权重,对示例图片进行推理,并将结果保存在runs/detect/exp/目录下。看到生成的带框图像,说明环境搭建成功。
数据组织:清晰结构决定成败
YOLOv5 对数据目录有明确要求。无论原始数据来自哪里,最终都必须整理成如下结构:
datasets/ └── my_dataset/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/其中:
-images/train存放训练图像(.jpg,.png等)
-labels/train存放对应的标签文件(.txt),命名需与图像一致
- 验证集同理
划分比例通常为 8:2 或 7:3。你可以手动分,也可以写个脚本自动完成:
import os import random import shutil image_dir = 'path/to/all/images' label_dir = 'path/to/all/labels' output_dir = 'datasets/my_dataset' os.makedirs(f'{output_dir}/images/train', exist_ok=True) os.makedirs(f'{output_dir}/images/val', exist_ok=True) os.makedirs(f'{output_dir}/labels/train', exist_ok=True) os.makedirs(f'{output_dir}/labels/val', exist_ok=True) # 获取所有图像文件名(不含扩展名) files = [f.rsplit('.', 1)[0] for f in os.listdir(image_dir) if f.lower().endswith(('.jpg', '.jpeg', '.png'))] random.shuffle(files) split_idx = int(0.8 * len(files)) train_files = files[:split_idx] val_files = files[split_idx:] for file in train_files: shutil.copy(f'{image_dir}/{file}.jpg', f'{output_dir}/images/train/{file}.jpg') label_file = f'{label_dir}/{file}.txt' if os.path.exists(label_file): shutil.copy(label_file, f'{output_dir}/labels/train/{file}.txt') for file in val_files: shutil.copy(f'{image_dir}/{file}.jpg', f'{output_dir}/images/val/{file}.jpg') label_file = f'{label_dir}/{file}.txt' if os.path.exists(label_file): shutil.copy(label_file, f'{output_dir}/labels/val/{file}.txt')注意:图像和标签必须严格一一对应,否则训练时会出现“找不到标签”或“空样本”的警告。
标注转换:VOC/COCO 如何适配 YOLO
YOLO 使用的是归一化的边界框格式,每个.txt文件内容如下:
<class_id> <x_center> <y_center> <width> <height>四个坐标值都是相对于图像宽高的比例(范围 0~1)。这与 Pascal VOC 的 XML 或 COCO 的 JSON 完全不同,因此需要做一次格式转换。
将 VOC XML 转为 YOLO TXT
以下是一个通用转换脚本:
import xml.etree.ElementTree as ET import os def convert_voc_to_yolo(xml_path, txt_path, class_names): tree = ET.parse(xml_path) root = tree.getroot() size = root.find('size') img_w = int(size.find('width').text) img_h = int(size.find('height').text) with open(txt_path, 'w') as f: for obj in root.findall('object'): cls_name = obj.find('name').text.strip() if cls_name not in class_names: continue cls_id = class_names.index(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_center = ((xmin + xmax) / 2) / img_w y_center = ((ymin + ymax) / 2) / img_h width = (xmax - xmin) / img_w height = (ymax - ymin) / img_h f.write(f"{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n") # 示例调用 class_names = ['person', 'car', 'truck', 'bus'] xml_dir = 'annotations/xmls' txt_dir = 'datasets/my_dataset/labels/train' os.makedirs(txt_dir, exist_ok=True) for xml_file in os.listdir(xml_dir): if xml_file.endswith('.xml'): name = xml_file[:-4] convert_voc_to_yolo( os.path.join(xml_dir, xml_file), os.path.join(txt_dir, f'{name}.txt'), class_names )⚠️ 关键提醒:class_names列表的顺序决定了类别 ID,后续配置文件中必须保持一致,否则会出现类别错乱!
配置文件:连接数据与模型的桥梁
在yolov5/data/下新建my_dataset.yaml:
path: ../datasets/my_dataset train: images/train val: images/val nc: 4 names: ['person', 'car', 'truck', 'bus']字段说明:
-path:数据集根目录,支持相对路径
-train/val:相对于 path 的子目录路径
-nc:类别数量
-names:类别名称列表,顺序不可错
这个文件会在训练时被train.py读取,用于加载数据和初始化分类头。
如果你想修改网络结构(比如加深层或调整通道数),可以复制models/yolov5s.yaml并重命名为yolov5_custom.yaml,然后修改其中的nc字段:
# models/yolov5_custom.yaml ... nc: 4 # number of classes ...训练时通过--cfg参数指定即可。
启动训练:一条命令开启旅程
一切准备就绪后,只需一条命令启动训练:
python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data data/my_dataset.yaml \ --weights yolov5s.pt \ --cfg models/yolov5s.yaml \ --name my_experiment参数详解:
---img:输入分辨率,越大越耗显存但细节保留更好
---batch:根据 GPU 显存调整,常见取值 8~32
---epochs:训练轮数,一般 50~300
---data:数据配置文件
---weights:预训练权重,强烈建议使用yolov5s.pt加速收敛
---cfg:模型结构文件(若未修改可省略)
---name:实验名称,结果保存在runs/train/my_experiment/
权重文件需提前下载并放入weights/目录:
🔗 下载地址:https://github.com/ultralytics/yolov5/releases
首次训练建议使用yolov5s.pt,它是轻量级与性能的良好平衡点。若设备资源有限,也可尝试yolov5n.pt(nano 版)。
模型评估与推理:检验成果
训练结束后,关键结果会保存在runs/train/my_experiment/中:
├── weights/ │ ├── best.pt ← mAP 最高的模型 │ └── last.pt ← 最后一轮的模型 ├── results.png ← 各项指标曲线(mAP@0.5, precision, recall 等) └── labels/ ← 验证集预测框可视化在验证集上测试性能
python val.py \ --weights runs/train/my_experiment/weights/best.pt \ --data data/my_dataset.yaml \ --img 640输出包括:
- Precision(精确率):检出的目标中有多少是正确的
- Recall(召回率):真实目标中有多少被成功检出
- mAP@0.5:0.95:IoU 从 0.5 到 0.95 的平均精度均值,综合评价指标
这些数值可以帮助你判断模型是否过拟合或欠拟合。
对新图像进行推理
实际部署中最常用的命令是detect.py:
python detect.py \ --weights runs/train/my_experiment/weights/best.pt \ --source inference/images/test.jpg \ --img 640 \ --conf-thres 0.5支持多种输入源:
- 单张图片:--source test.jpg
- 视频文件:--source video.mp4
- 摄像头:--source 0
- 图片目录:--source folder/
检测结果自动保存在runs/detect/expN/,包含原图叠加检测框的可视化图像。
实战建议与常见问题
显存不足怎么办?
这是最常见的问题。解决方法包括:
- 降低--batch-size(如从 16 改为 8)
- 使用更小的模型(yolov5n,yolov5s)
- 开启梯度累积(--gradient_accumulation_steps 4)
YOLOv5 内置了自动显存优化策略,但仍需根据硬件灵活调整。
如何判断是否收敛?
查看results.png中的曲线趋势:
- 如果 mAP 和 loss 已趋于平稳,说明基本收敛
- 若 val loss 上升而 train loss 下降,则可能过拟合
- 可提前终止训练或增加数据增强
权重备份很重要
训练过程中生成的best.pt是最有价值的产出,建议定期复制到安全位置,防止意外覆盖或磁盘损坏。
查看训练细节
YOLOv5 自动集成 TensorBoard 日志,可通过以下命令实时监控:
tensorboard --logdir=runs/train浏览器访问localhost:6006即可查看学习率、损失变化、特征图等丰富信息。
结语
从环境搭建到模型推理,这套流程看似繁琐,实则逻辑清晰、环环相扣。只要每一步都做到位,YOLOv5 很少会让你失望。
更重要的是,这套方法不仅适用于“人车路”检测,也能轻松迁移到其他领域:水果分级、零件缺陷、医学影像……只要你有标注数据,就能快速构建专属检测器。
技术本身没有高低之分,真正决定成败的,是你能否把每一个细节落到实处。
🚀最后的小建议:
- 新手优先使用yolov5s+ 默认参数,先跑通再调优
- 善用 Roboflow 等平台快速生成 YOLO 格式数据集
- 多看官方文档:https://docs.ultralytics.com/
坚持每天学一点,终有一天你会发现自己已经站在了起点之外很远的地方。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考