ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

网球数据集YOLO训练实战:从标签解析到多版本对比

网球数据集YOLO训练实战:从标签解析到多版本对比 简介这是一份面向YOLO系列目标检测学习者的网球场景数据集适用于yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等主流算法可直接用于模型训练与验证测试。数据集已按训练需求划分完毕并附带data.yaml配置文件省去自行整理与划分的繁琐步骤。压缩包共约2000个文件包含1707个xml标注文件与293个txt标注文件分别对应VOC格式与YOLO格式两种标签体系整体大小约87.8MB。其中YOLO格式采用类别索引与归一化中心点、宽高比例值记录目标框便于直接读取训练VOC格式则保留完整XML结构方便转换与复核。资源聚焦网球与运动员两类目标的识别任务适合作为课程设计、算法对比实验或迁移学习的基础数据。目前已有131人学习下载可帮助读者快速搭建可复现的检测流程减少数据准备环节的试错成本。1. 网球数据集到手之后1956 张图、双格式标签先别急着开训拿到一个标注好的网球数据集很多人的第一反应是直接yolo train跑起来看结果。但真正决定模型能不能收敛、mAP 能不能上去的往往不是网络结构而是你打开data.yaml那一刻有没有看懂路径、类别和划分。这份资源是 1956 张网球场景图像带完整标签已经划分好训练/验证集同时提供 YOLO 格式txt和 VOC 格式xml两套标注配了data.yaml可以直接喂给 yolov5、yolov8、yolov9、yolov7、yolov10、yolo11 这一系列算法。它解决的核心问题就一个省掉从零打标和格式转换的时间让你把精力放在训练调参和部署验证上。适合刚接触 yolo 系列目标检测、想拿一个真实运动场景数据集练手的人也适合需要快速验证某个改进点是否有效的从业者。下面我按「先看懂标签 → 再配环境 → 再训练 → 再排坑」的顺序拆一遍。2. 拆开标签文件YOLO 归一化坐标和 VOC 的对应关系2.1 一行 txt 里到底存了什么YOLO 格式的标签是每张图对应一个同名 txt里面每一行代表一个目标框格式是class x_center y_center width height。这里最容易翻车的是坐标含义x_center和y_center是框中心点相对整张图宽高的比例width和height也是相对比例四个值都在 0 到 1 之间。也就是说如果你拿到的 txt 里出现了大于 1 的数那基本可以判定标注工具导出时选错了格式或者图像尺寸信息丢了。拿项目正文里列出的img_0910_201.txt这类文件来说打开后大概率是这样0 0.512 0.634 0.087 0.152 0 0.301 0.488 0.064 0.121第一列0是类别索引从 0 开始。如果这个数据集只有网球一个类别那所有行的第一列都是 0。第二到第五列就是归一化后的中心点和宽高。这里有个血泪经验很多人用 labelImg 打完标导出时选了 YOLO 格式结果发现坐标全是 0 到 1 之间的小数以为出错了其实这才是对的反倒是导出成 VOC 的 xml 后看到像素绝对值才需要转换。2.2 VOC 的 xml 和 YOLO 的换算VOC 格式存在xml文件夹里结构是annotation下面有size记录图像宽高object里记录类别名和bndbox的xmin/ymin/xmax/ymax像素值。要把 VOC 转成 YOLO核心就四步# VOC xml - YOLO txt 转换核心逻辑 import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, img_w, img_h, class_map): tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.findall(object): cls_name obj.find(name).text cls_id class_map[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.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) return lines逻辑说明class_map是类别名到索引的映射必须和data.yaml里的names顺序一致否则训练时类别会错位。img_w和img_h从 xml 的size里读不要硬编码。参数上保留 6 位小数足够YOLO 官方也是这个精度。常见做法是写个批量脚本遍历整个 xml 文件夹输出到labels目录文件名保持和图片同名。2.3 data.yaml 里三个必须核对的字段数据集自带的data.yaml一般长这样path: ./tennis_dataset train: images/train val: images/val nc: 1 names: [tennis]path是数据集根目录train和val是相对path的图片路径。这里最常见的坑是路径写成了绝对路径换台机器就找不到或者train指向了images/train但标签实际在labels/trainYOLO 会自动把images替换成labels去找同名 txt所以目录结构必须是images/train和labels/train平行。nc是类别数names是类别名列表顺序必须和标签里的 class 索引严格对应。如果只有网球一类nc: 1names: [tennis]标签里第一列就只能是 0。3. 环境配置与训练启动从 conda 到第一轮 epoch3.1 yolov8 环境的最小依赖这个数据集适用多个 yolo 版本我一般先用 yolov8 跑通基线因为它的训练脚本最省心。环境配置上Anaconda 建一个 Python 3.9 或 3.10 的虚拟环境然后装 ultralyticsconda create -n yolo_tennis python3.10 -y conda activate yolo_tennis pip install ultralyticsultralytics包会自动带上 torch、torchvision 等依赖。如果你有 CUDA装完之后用python -c import torch; print(torch.cuda.is_available())确认一下是不是 True。常见做法是再装个opencv-python方便后面做推理可视化。注意不要混装多个 yolo 版本的包比如同时装了ultralytics和旧版yolov5的 requirements容易在 import 时冲突。3.2 用命令行启动训练确认data.yaml路径没问题后直接一行命令启动yolo detect train \ data./tennis_dataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ projecttennis_runs \ namebaseline参数说明modelyolov8n.pt是 nano 版本适合先跑通流程显存不够就降到batch8。imgsz640是输入分辨率如果原始图像长宽比差异大YOLO 会做 letterbox 填充。epochs100对 1956 张图来说够跑出一个可用的基线但要注意早停patience默认是 50如果验证集 loss 长时间不降会自动停。project和name决定输出目录权重会存在tennis_runs/baseline/weights/best.pt。3.3 训练过程中该盯哪几个指标启动后终端会打印每个 epoch 的 box_loss、cls_loss、dfl_loss 和 mAP50、mAP50-95。box_loss 管定位cls_loss 管分类dfl_loss 是分布焦点损失三个都降才说明模型在学。如果 box_loss 降但 cls_loss 不降大概率是类别标签有问题比如索引对不上或者有漏标。mAP50 在 20 个 epoch 内应该有明显上升如果一直卡在 0 附近先回去检查data.yaml的nc和names。我一般会在训练同时开一个终端跑nvidia-smi -l 1看显存占用防止 batch 设大了 OOM。3.4 验证集评估和单张推理训练完用best.pt在验证集上跑一遍yolo detect val \ modeltennis_runs/baseline/weights/best.pt \ data./tennis_dataset/data.yaml \ imgsz640输出会给出每类的 precision、recall、mAP50、mAP50-95。网球这种单类目标mAP50 上 0.9 不算难如果低于 0.7优先看验证集里有没有标注框明显偏移的图。单张推理用yolo detect predict \ modeltennis_runs/baseline/weights/best.pt \ source./test_image.jpg \ conf0.25 \ saveTrueconf0.25是置信度门限调低会出更多框但误检增加调高会漏检。这个参数没有万能值得根据你的场景在验证集上试几轮。4. 避坑与排查标签、路径、显存这三处最容易翻车4.1 现象训练启动就报 “No labels found”原因YOLO 默认按images目录名去推labels目录如果你的图片放在images/train标签却放在annotations/train或者txt/train它就找不到。解决把标签目录改成和images平级的labels或者直接在data.yaml里显式写train: images/train和val: images/val让 YOLO 自己替换。改完用ls labels/train | head确认 txt 文件名和图片名一一对应。4.2 现象mAP 一直是 0loss 不降原因data.yaml里的names顺序和标签里的 class 索引不一致。比如标签里网球是 0但names写成了[ball, tennis]模型学到的类别就全乱了。解决打开任意一个 txt看第一列的数字然后确保names列表里对应位置就是那个类别。单类数据集nc必须是 1names长度也必须是 1。4.3 现象训练到一半 CUDA out of memory原因batch设太大或者imgsz设成了 1280 而显存只有 6G。解决先把batch降到 8 或 4再不行就降imgsz到 512。另一个隐藏原因是workers设太高导致内存爆Windows 下建议workers0或 2。如果还不行用yolo detect train ... ampFalse关掉混合精度显存会省一点但速度慢。4.4 现象验证集指标很好实际推理漏检严重原因训练集和验证集划分不合理比如同一段视频的连续帧被分到了两边导致验证集“作弊”。解决检查数据集划分是不是随机按图分的如果是视频抽帧最好按视频段划分。另外看推理时的conf是不是设太高网球在远距离下目标小conf0.5可能全滤掉了降到 0.15 到 0.25 之间再试。4.5 现象VOC 转 YOLO 后框全部偏移原因xml 里的size宽高和实际图像尺寸不一致比如标注时图片被缩放过了。解决转换脚本里不要信 xml 里的 size直接用cv2.imread读原图拿真实宽高。如果原图已经找不到了那这批 xml 基本废了只能重新标。这也是为什么我建议优先用 YOLO 格式的 txt少一层转换少一层坑。5. 进阶技巧用 1956 张图把 yolo 系列算法横向对比一遍这份数据集真正的价值不只是“能训”而是它同时兼容 yolov5 到 yolo11你可以用同一份data.yaml和同一套划分把几个版本的基线跑出来做横向对比。具体做法是每个版本单独建一个 conda 环境避免包冲突然后统一用imgsz640、epochs100、batch16跑记录 mAP50、mAP50-95、推理耗时和模型大小。下面是我一般会填的对比表算法版本模型文件mAP50mAP50-95单张推理耗时(ms)权重大小(MB)yolov5syolov5s.pt待填待填待填待填yolov8nyolov8n.pt待填待填待填待填yolov8syolov8s.pt待填待填待填待填yolov10nyolov10n.pt待填待填待填待填yolo11nyolo11n.pt待填待填待填待填跑对比的时候有个细节yolov5 的仓库和 ultralytics 的 API 不一样yolov5 要用train.py脚本data参数指向同一个 yaml但hyp配置文件不同学习率和数据增强策略有差异。为了公平我一般把数据增强都关到最低只留 mosaic然后固定随机种子seed0。另一个技巧是导出 ONNX 后用onnxruntime测推理耗时比在 PyTorch 里测更接近部署真实情况。验证方法上除了看 mAP我还会抽 20 张验证集图片用每个版本的best.pt跑一遍把预测框画出来拼成一张对比图肉眼看看小目标网球有没有漏。有时候 mAP 只差 0.5 个点但实际漏检情况差很多尤其是球在画面边缘或者被球拍遮挡的时候。最后一步是把best.pt导出成 ONNXyolo export modeltennis_runs/baseline/weights/best.pt formatonnx imgsz640导出后可以用 Netron 打开看输入输出节点确认输出维度是[1, 5, 8400]这种格式单类时 5 4 个框坐标 1 个类别置信度。如果维度不对检查nc是不是设错了。从那以后我每次拿到新数据集都强制先跑一遍yolo detect train ... epochs1做冒烟测试确认标签路径、类别数和显存都没问题再开完整训练。这个习惯帮我省了至少十次跑了一晚上才发现标签全错的后悔药。希望帮到你。本文还有配套的精品资源点击获取
返回列表