YOLOv5从零到一:手把手教你构建与训练专属数据集
1. 环境准备与数据收集
第一次接触YOLOv5时,最让人头疼的就是如何把一堆原始图片变成模型能"吃"的数据。这就像要给挑食的孩子准备便当,得先了解他的口味。YOLOv5支持的数据格式主要有三种:VOC、COCO和YOLO格式,我们这次重点讲最常用的YOLO格式。
我建议先创建一个专门的项目目录,比如yolov5_project,里面再建两个子文件夹:
raw_images:存放原始图片(建议用JPG或PNG格式)raw_labels:准备存放标注文件
注意:图片命名不要用中文或特殊字符,最好用连续数字或字母编号,比如
img_001.jpg
实测中发现,图片尺寸差异过大会影响训练效果。可以用这个Python脚本批量调整大小:
from PIL import Image import os input_dir = 'raw_images' output_dir = 'resized_images' target_size = (640, 640) # YOLOv5默认输入尺寸 if not os.path.exists(output_dir): os.makedirs(output_dir) for filename in os.listdir(input_dir): img = Image.open(f'{input_dir}/{filename}') img = img.resize(target_size, Image.BILINEAR) img.save(f'{output_dir}/{filename}')2. 数据标注实战技巧
2.1 标注工具选型
推荐三款主流标注工具:
- LabelImg:新手友好,支持VOC和YOLO格式导出
- CVAT:功能强大适合团队协作
- Roboflow:在线工具带自动标注功能
以LabelImg为例,安装命令很简单:
pip install labelImg labelImg # 启动图形界面标注时容易踩的坑:
- 标注框要完全包裹目标物体,但不要留太多空隙
- 不同类别的物体要用不同标签(如"cat"、"dog")
- 遇到遮挡物体时,按可见部分标注
2.2 标注文件格式转换
YOLOv5需要的标注格式是每张图片对应一个.txt文件,内容类似:
0 0.5 0.5 0.3 0.4 # 类别ID x_center y_center width height这个转换脚本可以把LabelImg的XML转成YOLO格式:
import xml.etree.ElementTree as ET import os classes = ["cat", "dog"] # 你的类别列表 def convert(size, box): dw = 1./size[0] dh = 1./size[1] x = (box[0] + box[1])/2.0 y = (box[2] + box[3])/2.0 w = box[1] - box[0] h = box[3] - box[2] x = x*dw w = w*dw y = y*dh h = h*dh return (x,y,w,h) for xml_file in os.listdir("Annotations"): tree = ET.parse(f"Annotations/{xml_file}") root = tree.getroot() with open(f"labels/{xml_file[:-4]}.txt", 'w') as f: size = root.find('size') w = int(size.find('width').text) h = int(size.find('height').text) for obj in root.iter('object'): cls = obj.find('name').text if cls not in classes: continue cls_id = classes.index(cls) xmlbox = obj.find('bndbox') b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text)) bb = convert((w,h), b) f.write(f"{cls_id} {' '.join([str(a) for a in bb])}\n")3. 数据集划分与配置
3.1 划分训练集/验证集
建议按8:2的比例拆分,这个脚本可以自动划分:
import os import random image_files = [f for f in os.listdir("images") if f.endswith('.jpg')] random.shuffle(image_files) split = int(0.8 * len(image_files)) train = image_files[:split] val = image_files[split:] with open('train.txt', 'w') as f: for img in train: f.write(f"data/custom/images/{img}\n") with open('val.txt', 'w') as f: for img in val: f.write(f"data/custom/images/{img}\n")3.2 创建数据集配置文件
在yolov5/data/下新建custom.yaml,内容示例:
train: ../train.txt val: ../val.txt nc: 2 # 类别数量 names: ['cat', 'dog'] # 类别名称4. 模型训练与调优
4.1 选择预训练模型
YOLOv5提供四种规格的模型:
- yolov5s:速度最快,精度最低
- yolov5m:平衡型
- yolov5l:高精度
- yolov5x:极致精度
新手建议从yolov5s开始:
python train.py --img 640 --batch 16 --epochs 100 --data data/custom.yaml --cfg models/yolov5s.yaml --weights yolov5s.pt4.2 关键参数解析
--img 640:输入图像尺寸--batch 16:根据GPU显存调整(显存不足时减小)--epochs 100:训练轮次(建议50-300)--weights yolov5s.pt:加载预训练权重
训练过程中可以用TensorBoard监控:
tensorboard --logdir=runs5. 常见问题解决方案
5.1 CUDA内存不足
报错CUDA out of memory时:
- 减小
--batch-size(比如从16降到8) - 减小
--img-size(比如从640降到512) - 使用
--adam优化器(比默认SGD省内存)
5.2 标注文件不匹配
确保:
- 每个图片都有对应的.txt标注文件
- 标注文件中的类别ID从0开始连续编号
- 坐标值在0-1范围内
5.3 训练指标不理想
可以尝试:
- 增加数据量(至少每类100张以上)
- 调整学习率(
--lr 0.01) - 启用数据增强(
--augment True)
最后提醒,训练完成后别忘了测试模型效果:
python detect.py --weights runs/exp/weights/best.pt --source test_images/