资讯动态

YOLO目标检测数据集标签转换与训练全流程实战指南

发布时间:2026/9/24 19:02:38 来源:尧图企业网站定制
简介面向目标检测开发者的YOLO泄露目标数据集资源包提供高质量标注数据聚焦真实场景下的目标检测任务解决训练数据难获取、标注成本高的问题。资源含1000张图片及多种格式标签文件总数2000个以VOC格式xml标签、YOLO格式txt标签为主另含YAML配置、Python划分脚本与HTML教程压缩包大小33.75MB目录分类清晰便于按需调用。配套内容突出实用性提供Linux/Windows双平台YOLO环境搭建与训练教程可根据案例修改训练自己的数据集附带训练集/验证集/测试集划分脚本支持按需求自动生成新文件夹与ImageSets下的txt文件省去手动整理标签的麻烦。目前已有229人学习下载适合目标检测入门学习者与需要快速获取可用数据集的进阶开发者。1. 拿到YOLO泄露目标数据集之后先别急着开训把三套标签捋一遍第一次解压这份YOLO泄露目标数据集时我盯着文件夹里并列的voc、coco、yolo三个子目录愣了几秒。一千张真实场景图片三份坐标完全一致、格式完全不同的标签外加一套HTML教程和三个Python划分脚本这种组合比一个“理得干干净净”的数据集更让人放心——它把从标注到训练的全过程留在了原地而不是只丢给你一个结果。它解决三件事标签格式互转不再靠猜划分训练集、验证集、测试集不用每次重写脚本环境搭建和训练路径已经有人替你踩过一遍。适合刚搭好环境、想用自己的数据完整跑通一次YOLO训练的人也适合想对照VOC、COCO、YOLO三种标签差异的老手。2. VOC、COCO、YOLO三套标签同一张图为什么存三份2.1 拆包先看目录三套文件夹各管什么把压缩包解开之后除了三个HTML说明文档和三个py脚本剩下的就是数据集主体。我按惯例先列了一遍目录布局大致长这样data/ ├── images/ # 1000张原始图片 ├── Annotations/ # VOC格式的xml标签 ├── labels/ # YOLO格式的txt标签 └── coco.json # COCO格式标签第一次看到这个布局的人多半会问一句同一张图为什么要把标签存成三份原因很简单。YOLO系列训练脚本直接吃txt一个txt文件名对应一张图每行一个目标COCO的json则是整个数据集一个文件目标检测的评估工具比如pycocotools只认这种结构VOC的xml是很多老项目和数据管理工具默认的标注存档格式。一个数据集要同时喂给这三条链路最省事的办法就是像这份资源一样把同一批标注同时导出成三份互不影响。这里需要理解的是这三份标签描写的都是同一个矩形框只是写法不同。VOC的xml用bndbox节点里面是xmin、ymin、xmax、ymax四个像素坐标COCO的json用annotations数组每个框是bbox属性存[x, y, width, height]YOLO的txt则是每行class_id、x_center、y_center、width、height前两个是归一化中心点坐标后两个是归一化宽高全部除以图片宽高算出来的。这套对应关系是后面所有操作的地基包括用labelimg重新打开标注、手动修错框、以及跨项目迁移数据。2.2 三种格式的坐标其实是同一个框三种格式之间的换算说穿了就是乘除图片宽高。把归一化坐标乘回像素坐标公式是x_min (x_center - width / 2) * Wy_min (y_center - height / 2) * Hx_max (x_center width / 2) * Wy_max (y_center height / 2) * H反过来的方向则是把像素坐标除以W/H。COCO的bbox[x, y, width, height]和VOC的[xmin, ymin, xmax, ymax]之间差一个加减宽高的步骤。这个转换看着简单实际翻车率很高我见过有人把归一化中心点0.5直接当成像素坐标去画框框全挤在左上角检查半天都找不到原因。下面这张表列出三种格式的关键字段对照修改标签时可以逐行核对格式文件形态坐标描述类别描述VOC(xml)每张图一个xmlbndbox里的xmin,ymin,xmax,ymax像素object节点里的name字符串COCO(json)整个数据集一个jsonannotations.bbox的[x,y,w,h]像素categories里id与name的映射YOLO(txt)每张图一个txt每行class_id,x_center,y_center,width,height归一化行首整数class_id与训练配置里的names索引一致最后那一行值得再强调一遍YOLO txt里那串class_id不是标签名是序号。data.yaml里names列表第0项对应class_id 0第1项对应class_id 1顺序一错训练出来的模型就会把“人”认成“车”。这份数据集用labelimg标注labelimg保存为YOLO格式时就是按界面里定义的类别顺序写文件所以拿到手先别急着改标签先把names顺序背熟再用尤其是后续要增加类别时顺序错一个都牵一发动全身。2.3 怎么确认标签和图片对得上半小时画完一千张拿到任何数据集我做的第一件事不是训练而是随机抽三张图把标签画回原图上看。这个动作能过滤掉绝大多数数据问题比任何训练前的清洗都管用。常见做法是读一个txt把归一化坐标还原成像素坐标然后用OpenCV画框。import cv2 img cv2.imread(images/0001.jpg) # 换成你要验证的图片路径 H, W img.shape[:2] # 原图的真实高度和宽度 with open(labels/0001.txt, r) as f: # yolo格式标签 for line in f: cls_id, xc, yc, w, h map(float, line.split()) x1 int((xc - w / 2) * W) y1 int((yc - h / 2) * H) x2 int((xc w / 2) * W) y2 int((yc h / 2) * H) cv2,rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite(check.jpg, img) # 画框结果另存别直接覆盖原图这段代码的逻辑是把txt里的归一化中心点和宽高乘回图片宽高得到像素坐标再画绿色矩形。cls_id变量是类别序号画框时没用到但调试时建议打印出来跟data.yaml里的names逐行对一遍。cv2.imwrite会覆盖同名文件所以要另存为check.jpg。如果画出来的框整体偏移、大小不对问题多半出在归一化公式的乘除顺序上仔细核一遍再继续。如果图片后缀不是jpg而是png把第2行里的后缀一起改过来就行。这里花上二十分钟把可疑框找出来比后面训练完再回头改数据划算得多这个原则在我后面所有项目里都没变过。3. 划分脚本实际怎么用三份脚本的分工与参数3.1 先搞清楚三份脚本分别干什么随包带着三个划分脚本文件名写得很直白但第一次接触的人容易混淆。列一张表说明脚本文件名输出结果适用场景训练集、验证集、测试集划分脚本图片标签划分写入新文件夹.pytrain/val/test三个目录需要完整评估模型泛化能力训练集、验证集划分脚本图片标签划分写入新文件夹.pytrain/val两个目录数据量小或只需快速看训练效果split_train_val生成ImageSets下txt文件划分脚本.pyImageSets/Main下的txt文件沿VOC老链路训练或做标签管理另外包里还有一个train_list.txt那是划分脚本生成的图片清单VOC系工具链里常要用到。三个脚本的核心动作都是同一件事读取全量图片按比例随机分成若干份再把图片和对应标签成对拷贝到新目录。区别在于输出形态前两个直接建目录第三个只生成txt清单配合原有目录结构使用。3.2 命令行跑通一次先分后训测试集留在最后脚本建议用命令行跑而不是在IDE里双击。在压缩包解压后的目录打开终端先确认Python能跑python --version python 训练集、验证集、测试集划分脚本图片标签划分写入新文件夹.py如果终端提示python不是内部或外部命令说明Windows环境变量没配好换成python3再试一次。脚本执行后会在当前目录或设置的输出目录下生成train、val、test三个文件夹每个文件夹里再分images和labels两个子目录。看到目录结构生成再去检查三个目录里的图片数量是否和预期比例一致。这个顺序很重要划分一定要在训练之前做。YOLO训练时会按照data.yaml里的train和val路径读图如果这两个路径指向同一堆图片验证集形同虚设得到的mAP会虚高换一批真实图片就露馅。测试集则是训练全程都不该碰的牌只在最终验收时用。包内脚本已经把目录划分成train/val/test三个只需在data.yaml里把路径指过去。3.3 自己改一版划分脚本核心逻辑和参数说明包里的脚本开箱即用但不同数据的目录命名不一样改起来要花时间。我更习惯保留一个通用划分脚本遇到新数据集时直接填配置区。下面这个版本就是这类脚本的核心逻辑先扫描图片再按比例打乱切片最后成对拷贝图片和同名txt。import os import random import shutil random.seed(42) # 固定随机种子保证每次划分结果一致 # 配置区按自己的目录改这三行 source_images images # 原始图片目录 source_labels labels # yolo标签目录txt与图片同名 output_root leak_split # 划分输出根目录 train_ratio, val_ratio, test_ratio 0.7, 0.2, 0.1 # 比例总和必须是1 image_files [f for f in os.listdir(source_images) if f.endswith(.jpg)] random.shuffle(image_files) # 打乱顺序防止连续抓拍的相似图进同一个子集 n_train int(len(image_files) * train_ratio) n_val int(len(image_files) * (train_ratio val_ratio)) sets { train: image_files[:n_train], val: image_files[n_train:n_val], test: image_files[n_val:], } for split_name, file_list in sets.items(): img_dir os.path.join(output_root, split_name, images) lab_dir os.path.join(output_root, split_name, labels) os.makedirs(img_dir, exist_okTrue) os.makedirs(lab_dir, exist_okTrue) for img_name in file_list: base os.path.splitext(img_name)[0] shutil.copy2(os.path.join(source_images, img_name), img_dir) txt_path os.path.join(source_labels, base .txt) if os.path.exists(txt_path): shutil.copy2(txt_path, lab_dir) # 只拷存在的标签避免中断 print(ftrain: {len(sets[train])}, val: {len(sets[val])}, test: {len(sets[test])})这段代码里有几个点值得留意。random.shuffle在切片之前做是为了让连续拍摄的相似场景分散到不同子集否则同一监控点位的画面会同时占据训练集和验证集评估结果虚高。n_val的计算用train_ratio加val_ratio再用列表切片往后切test自然就是剩下那部分。拷贝用shutil.copy2保留原始数据当后悔药不做剪切移动。copy2还会保留文件修改时间排查文件是否被程序改动过时很有用。random.seed(42)这行决定了可复现性想换一组划分就把数字改成别的整数。参数上train_ratio、val_ratio、test_ratio三者相加必须等于1如果只分训练集和验证集把test_ratio设成0.0脚本会自然跳过test目录。endswith(.jpg)那行只认jpg图片是png就改成endswith(.png)。如果jpg和png混着来可以用os.path.splitext取后缀再判断。脚本执行完后去三个目录数一遍数量达到预期就进入下一步。分包里的脚本如果报找不到图片多半是解压路径里有中文或空格把整个文件夹移到纯英文路径下重跑一次。4. Linux和Windows各有一份训练教程版本匹配比敲命令更重要4.1 Linux上用anaconda建环境先确认CUDA再动手包里附带Linux和Windows两套HTML教程我的建议是先按Linux版跑通一次流程再回到Windows复现。Linux下没有路径分隔符和历史包袱出问题更容易定位。环境搭建的起点是Anaconda用conda创建一个独立环境避免把python、torch和其他项目搅在一起conda create -n yolo python3.9 -y conda activate yolo pip install ultralytics python -c import torch; print(cuda available:, torch.cuda.is_available())第一行创建名叫yolo的干净环境python版本固定成3.9这是ultralytics系列里测试比较充分的一组配置。第三行pip install ultralytics会连带把torch、torchvision、opencv这些依赖一起装好不需要手动逐个安装。最后一行是检验GPU是否生效的关键命令输出True说明显卡能被torch调用输出False说明torch装的是CPU版本或者显卡驱动和CUDA版本对不上。常见做法是先用nvidia-smi看驱动支持的CUDA版本再按这个版本去装对应的pytorch。在线安装太慢就换国内镜像源装。我一般会在正式训练前先跑一行yolo的预测命令拿官方权重推理一张示例图确认整条链路通再开始处理自己的数据集。这一步能省出不少在训练中途才发现环境问题的冤枉时间。4.2 Windows版教程的坑路径分隔符和模型下载Windows版HTML教程的流程和Linux基本一样真正卡人的是两个细节。第一个是路径data.yaml里如果写的是C:\Users\xxx\datasets这种反斜杠路径YAML解析器会把反斜杠当转义字符处理训练启动时直接报错。解决方案很直接把yaml里的所有路径改成斜杠或者干脆用相对路径data.yaml放在数据集根目录下写train: train/imagesval: val/images。第二个是权重文件下载。训练命令里指定的预训练权重比如yolov8n.pt第一次运行时需要联网下载。如果下载失败训练就卡在初始化阶段。解决办法是手动把权重文件下载后放到当前目录重新执行训练命令程序检测到本地已有该文件就不会再尝试下载。Windows上的训练命令在Anaconda Prompt里执行先激活环境再跑conda activate yolo yolo detect train datadata.yaml modelyolov8n.pt epochs100 imgsz640 batch16epochs控制训练轮数100对一千张图来说偏多数据集小的话50轮基本就收敛了imgsz是输入图片尺寸640是YOLO系列的常用值不要为了省显存随便降到416会明显损失小目标检测能力batch大小看显存16在12G显存上没问题显存小就降到8或4。训练结束后结果会落在runs/detect/train目录下weights子目录里有best.pt和last.pt两个权重文件best.pt是验证集上综合表现最好的那个后面预测和部署都用它。4.3 HTML教程教会的是流程不是固定参数包内教程的标题写得很清楚是“根据案例修改训练自己的数据集”。我的经验是把它当流程参考而不是字面照抄。里面的数据集路径、类别顺序、模型规模都需要替换成你自己的。尤其类名列表教程里的案例类目必然是作者数据集的一定要改。这一块最容易翻车我见过有人用教程原有的类别数训练自己的数据训练完才发现输出维度不对。血泪经验是每次改数据集之后先用best.pt跑一张图看看预测出来的类别和框有没有对上。这一步的改错成本比训练完再发现低得多。5. 常见排查五个绕不开的坑5.1 划分后提示No labels found in train set现象训练刚开始终端弹出Warning和一句话No labels found in train set。然后训练不启动或者启动后loss一直是0。原因划分脚本只拷了图片没拷标签。常见场景是标签目录名不是labels脚本里的源路径写错或者源标签是xml格式而训练需要txt。解决先检查划分后train目录下有没有txt文件。没有就回脚本配置区把source_labels改成正确的标签目录如果只有xml先把xml批量转成yolo格式再重新划分。验证方式是在划分后跑一遍脚本自带的统计代码打印出图片数和标签数两边一致才继续。5.2 Windows上报ValueError: Expected : but found 现象在Windows上启动训练YAML解析时报错ValueError: Expected : but found 指向data.yaml文件里的路径行。原因Windows路径习惯用反斜杠比如C:\Users\admin\data.yamlYAML把反斜杠当成转义符路径被解析得面目全非。解决把data.yaml里所有路径改成正斜杠。更稳的是用相对路径data.yaml放在数据集根目录train、val、test填相对路径这样跨机器复用也不受盘符影响。凡是yaml里写路径我从来不用反斜杠这条规则一劳永逸。5.3 训练到一半loss变成nan现象训练进度里yolo损失函数在前几十轮正常下降某个时刻突然变成nan之后一直nan不再恢复。原因常见是学习率设置过高导致梯度爆炸或者batch开太大爆显存后数值异常。换数据集时类别数改了但模型配置里nc没改也会出现这类问题。解决先检查data.yaml里的nc和names类别数量必须和标签里出现的最大class_id加1一致。然后把学习率降到默认值的十分之一batch降到4重新训练。如果loss在几百轮后仍不降把预训练权重去掉再试一轮。5.4 labelimg标注时看着没错训练后类别全乱现象标注时框的位置都正确预测出来的类别却和实际对不上比如把“人”的框全部识别成“车”。原因labelimg保存yolo标签时txt行首写的class_id由界面右侧的类别列表顺序决定。如果训练配置里的names顺序和这个列表不一致class_id指向的名字就错位了。解决打开任意一个txt看第一行开头的数字再对照data.yaml里names列表从0开始数。把classes.txt和data.yaml里的names逐行对齐不一致就调整其中一边。改完重训之前先拿一张图推理确认类别名称能对上。这个是yolo训练自己的数据集时最隐蔽的坑动手前值得花两分钟做一次对齐。5.5 验证集mAP虚高测试集形同虚设现象训练日志里的mAP50能到0.9以上模型看着很厉害换一批没见过的图片推理漏检和误报却很严重。原因划分脚本没用测试集或者划分时没打乱顺序相似的连续帧同时进了训练集和验证集。mAP是在验证集上算出来的训练时模型已经见过这些画面指标自然好看。解决确认划分脚本生成了三个目录再验证train、val、test三个子集没有重叠。上一章的通用脚本里random.seed(42)和shuffle做好之后这个错就不会再犯。如果已经分完才发现重叠直接重跑一遍划分脚本源数据还在随时能重来。6. 训练完先别急着收工用mAP和预测图验收模型6.1 先用验证集算mAP再看50-95这个指标训练结束时日志里的mAP50容易让人错觉真正说明问题的是mAP50-95。前者只算IoU等于0.5的匹配后者把0.5到0.95每隔0.05算一次再取平均框稍微偏一点就掉分。打开终端跑一遍验证yolo detect val datadata.yaml modelruns/detect/train3/weights/best.pt跑完后终端会给出mAP50、mAP50-95和每个类别的AP。如果mAP50还行mAP50-95明显偏低说明框的整体位置偏了回头调标注质量比调模型参数收益更大。这份数据集的标签是人工标注的漏标和框偏是常态用指标反过来定位标注问题比肉眼翻一千张图高效得多。6.2 用真实图片预测一轮再调置信度阈值验证集指标过关不等于部署能用。我一般会在训练完用best.pt预测几张训练时没见过的照片看框的位置和类别对不对yolo detect predict modelruns/detect/train3/weights/best.pt sourcetest_images conf0.25conf是置信度阈值0.25是常用默认值。阈值调低漏检变少但误检框会变多阈值调高则反过来。部署时如果监控场景误检率高把conf往上抬到0.4或0.5往往比重新训练更立竿见影。预测结果默认保存在runs/detect/predict目录里每张图一个可视化结果一张张翻完才算验收结束。从那以后我每拿到一个新数据集都强制把类别顺序对一遍、跑一次划分脚本、算一次mAP50-95最后用真实图预测一轮才敢说训练完了。这套流程看着繁琐但每次都能在正式训练前把数据问题揪出来省下的重训时间比这点功夫值钱得多。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价