ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

鸭子数据集VOC和YOLO双格式:348张图快速跑通YOLO训练与VOC转YOLO实战

2026/10/7 13:10:19 拓冰建站 浏览量
鸭子数据集VOC和YOLO双格式:348张图快速跑通YOLO训练与VOC转YOLO实战 简介这份鸭子目标检测数据集面向计算机视觉初学者与算法验证人员用于训练和测试duck类目标检测模型。资源共1039个文件以346张jpg图片、346个xml标注文件和347个txt标注文件为主图片与标注一一对应压缩包约25.28MB解压后无需密码即可直接查看。所有图片均由labelImg人工标注类别统一为duck标注时尽量准确框选目标边界、覆盖画面中全部鸭子并经过一致性检查以减少漏标与误标。VOC格式的xml适合Pascal VOC训练流程yolo格式的txt可直接接入YOLO系列模型省去格式转换环节。目前已有130人学习适合快速搭建小规模检测实验、验证数据增强与模型调参效果。1. 鸭子数据集 VOC 和 YOLO 双格式348 张图能直接跑起来吗上周有个做养殖场巡检的朋友发来一张截图问我能不能用现成数据先把鸭子检测的链路跑通再谈自己拍图标注的事。我翻了一圈公开资源发现这份 348 张的鸭子数据集正好卡在一个很舒服的位置量不大但 VOC 和 YOLO 两套标注都齐了jpg 图片、xml、txt 各 348 份解压就能用。它不是那种动辄几万张、下载要挂一晚上的大库也不是只有几十张、训两轮就过拟合的玩具集。对想验证 YOLO 训练流程、想练 VOC 转 YOLO 格式转换、想拿真实标注练手 mAP 计算的人来说这份数据集的性价比在于「当天就能看到 loss 曲线动起来」。标注工具是 labelImg类别只有一个 duck边界框质量按标注规范做了边界框选、全目标覆盖和一致性检查。下面我按实际拆包、转格式、训练、排错的顺序把这份资源怎么落地讲清楚。2. 拆包先看目录结构VOC 与 YOLO 到底差在哪2.1 三个文件夹的职责划分解压后你会看到三个文件夹这是这份数据集最省心的地方——图片、VOC 标注、YOLO 标注物理隔离不会出现图片和 xml 混在一起、找文件找到眼瞎的情况。常见做法是图片文件夹348 张 jpg命名形如duck_104.jpg、duck_217.jpg编号不连续是正常的说明是从更大图库里筛出来的子集。xml 文件夹348 份 VOC 标注每份对应一张图文件名与图片同名不同后缀。txt 文件夹348 份 YOLO 标注同样是同名不同后缀。这里有个容易翻车的点很多人拿到数据集第一反应是「图片和标注放一起不就行了」但 VOC 和 YOLO 两套标注同时存在时混放会让后续脚本遍历时把 xml 和 txt 都当成标注读进去导致重复计数。保持三文件夹分离转换和训练各取所需是最稳的做法。2.2 VOC 的 xml 里到底存了什么VOC 格式的核心是 xml用文本编辑器打开一份duck_104.xml你会看到size里的宽高、object里的类别名和bndbox里的 xmin/ymin/xmax/ymax。这几个值决定了后面转 YOLO 时归一化坐标算得对不对。我一般会先抽查三到五份 xml确认xmax xmin、ymax ymin且坐标不超出图片宽高。这份数据集标注时做了边界框选和一致性检查抽查下来坐标越界的概率很低但抽查这一步不能省——一旦有脏框训练时 loss 会莫名其妙地跳。2.3 YOLO 的 txt 与 VOC 的换算关系YOLO 的 txt 每行是类别索引 中心x 中心y 宽 高全部归一化到 0~1。它和 VOC 的换算关系是cx (xmin xmax) / 2 / img_w cy (ymin ymax) / 2 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h这份数据集已经帮你把 txt 算好了所以如果你直接用 YOLO 训练可以跳过转换。但如果你要用 VOC 评估工具、或者想自己写转换脚本练手xml 那套就是原料。两套都留着的好处是训练用 txt验证和可视化用 xml互不打架。3. 用这份数据集跑通 YOLO 训练从 data.yaml 到第一轮 loss3.1 目录重排与 data.yaml 写法YOLO 训练对目录有固定期待常见做法是把 348 张图按 8:2 切成 train/val图片和 txt 分别放到images/train、images/val、labels/train、labels/val。下面这段脚本我一般用来做切分注意它同时搬运图片和同名 txtimport os, shutil, random src_img duck/images # 解压后的图片文件夹 src_lbl duck/txt # 解压后的 YOLO 标注文件夹 dst duck_yolo random.seed(42) # 固定随机种子保证切分可复现 files [f for f in os.listdir(src_img) if f.endswith(.jpg)] random.shuffle(files) split int(len(files) * 0.8) # 8:2 切分 for i, f in enumerate(files): phase train if i split else val stem os.path.splitext(f)[0] shutil.copy(os.path.join(src_img, f), os.path.join(dst, images, phase, f)) shutil.copy(os.path.join(src_lbl, stem .txt), os.path.join(dst, labels, phase, stem .txt))逻辑说明random.seed(42)是为了让每次切分结果一致方便复现实验split取 80% 做训练348 张里约 278 张训练、70 张验证。参数上如果你的显存小、想更快看到结果可以把比例调到 9:1但验证集低于 30 张时 mAP 波动会很大不建议再低。切分完写data.yamlpath: ./duck_yolo train: images/train val: images/val nc: 1 names: [duck]nc是类别数这份数据集只有 duck 一类所以是 1names的顺序必须和 txt 里的类别索引对应单类别时索引就是 0。3.2 训练命令与关键参数用 YOLOv8 起步的话一条命令就能跑yolo detect train \ dataduck_yolo/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ patience20 \ projectduck_run \ nameexp1参数说明modelyolov8n.pt是最小的预训练权重348 张图用 nano 版足够换 s 或 m 版容易过拟合imgsz640是常见输入尺寸和预训练权重匹配batch16在 8G 显存上比较稳显存不够就降到 8patience20表示 20 轮没提升就早停小数据集上这个值能帮你省时间。跑起来后重点看mAP50和box_loss前 10 轮 loss 下降、mAP 从 0 往上爬说明链路通了。3.3 验证与可视化训练完在duck_run/exp1/weights/下会有best.pt和last.pt。验证用yolo detect val modelduck_run/exp1/weights/best.pt dataduck_yolo/data.yaml想直观看框得准不准用 predict 把验证集跑一遍输出图会画上预测框yolo detect predict modelduck_run/exp1/weights/best.pt \ sourceduck_yolo/images/val saveTrue conf0.25conf0.25是置信度阈值调低会多出框、调高会漏框小数据集上我一般先在 0.25 看整体再针对漏检调到 0.15 复查。4. VOC 转 YOLO 自己写一遍脚本、参数与边界坑4.1 为什么还要自己转数据集已经给了 txt为什么还要写转换脚本两个原因一是你以后拿到的 VOC 数据集未必带 YOLO 版转换是通用技能二是自己转一遍能校验这份数据集的 txt 和 xml 是否一致相当于做了一次数据质检。下面这个脚本读 xml、写 txtimport os, xml.etree.ElementTree as ET classes [duck] # 类别顺序决定索引 xml_dir duck/xml out_dir duck/txt_check os.makedirs(out_dir, exist_okTrue) for fn in os.listdir(xml_dir): if not fn.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, fn)) root tree.getroot() w int(root.find(size/width).text) h int(root.find(size/height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in classes: continue # 跳过非目标类别 b obj.find(bndbox) xmin float(b.find(xmin).text) ymin float(b.find(ymin).text) xmax float(b.find(xmax).text) ymax float(b.find(ymax).text) # 裁剪到图像边界防止越界框 xmin, ymin max(0, xmin), max(0, ymin) xmax, ymax min(w, xmax), min(h, ymax) cx (xmin xmax) / 2 / w cy (ymin ymax) / 2 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{classes.index(name)} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) with open(os.path.join(out_dir, fn.replace(.xml, .txt)), w) as f: f.write(\n.join(lines))逻辑说明classes的顺序必须和训练时data.yaml的names一致否则类别索引错位模型学到的就是错的坐标裁剪那两行是防越界的关键VOC 里偶尔会有框超出图像边界的脏数据不裁的话归一化后会出现大于 1 的值YOLO 读取时会报错或静默丢弃。:.6f保留六位小数是 YOLO 常见精度够用且不冗长。4.2 转换后的校验转完别急着训先做一致性校验把txt_check和数据集自带的txt逐文件比对看行数和数值是否接近。完全一致说明数据集标注规范有差异就抽查对应图片看是自带 txt 有问题还是你的脚本漏了类别。这一步花十分钟能省掉训练时几小时的排查。4.3 参数怎么改类别名不是 duck改classes列表同时改data.yaml的names。多类别classes按你的顺序排classes.index(name)会自动给出正确索引。图片格式不是 jpg脚本只读 xml图片格式不影响转换但训练时data.yaml指向的图片路径要对。5. 避坑与排查348 张小数据集最容易翻车的五件事5.1 现象训练 loss 不降mAP 一直是 0原因最常见的是data.yaml里names和 txt 里的类别索引对不上或者nc写成了 0。另一个可能是图片路径写错YOLO 找不到图拿空标签在训。解决先跑一遍yolo detect val看能不能读到数据再抽查一份 txt确认第一列是 0最后核对data.yaml的path是相对还是绝对路径相对路径的基准是运行命令的目录不是 yaml 所在目录。5.2 现象验证集 mAP 高得离谱接近 1.0原因训练集和验证集切分时没固定种子或者图片和标注没同步搬运导致验证集里混进了训练图模型等于在背答案。解决切分脚本里加random.seed并且图片和同名 txt 必须成对搬运。切完可以统计 train 和 val 的文件名交集交集不为空就是漏了。5.3 现象预测框位置整体偏移原因VOC 转 YOLO 时用了错误的图片宽高比如把 xml 里的 size 当成缩放后的尺寸或者归一化时除错了数。解决确认 xml 的size是原图尺寸转换脚本里w、h直接取自 xml不要用固定值。如果数据集图片被预处理过size 必须同步更新。5.4 现象某些图完全没有框原因标注时漏标或者 txt 里对应行被写成了空文件。这份数据集标注规范里强调了全目标覆盖但 348 张里仍可能有极少数漏网。解决写个脚本统计每份 txt 的行数行数为 0 的挑出来人工复查图片。如果确实无目标训练时这类图可以保留作为负样本但比例不能高。5.5 现象训练到一半显存爆了原因batch设太大或者imgsz从 640 调到了 1280 却没降 batch。解决8G 显存上imgsz640配batch16是安全线调到 1280 就把 batch 降到 4 或 8。也可以用yolo detect train ... batch-1让框架自动找最大 batch但自动值有时偏激进跑之前先看显存占用。6. 把 348 张用到极致小数据集的增强与验证技巧348 张对目标检测来说属于小样本直接训容易过拟合但这份数据集的价值恰恰在于「小到能快速迭代」。我一般会做两件事一是开 YOLO 自带的增强二是用交叉验证代替单次切分。增强参数在训练命令里加yolo detect train \ dataduck_yolo/data.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch16 \ hsv_h0.015 hsv_s0.7 hsv_v0.4 \ degrees10 translate0.1 scale0.5 \ fliplr0.5 mosaic1.0hsv_h/s/v是色调、饱和度、亮度扰动鸭子毛色在不同光照下差异大这三个值能提升泛化degrees10是小角度旋转养殖场俯拍时角度不会太夸张别开到 90fliplr0.5水平翻转鸭子左右对称翻转安全mosaic1.0是四图拼接小数据集上几乎必开能显著增加每轮看到的组合。注意mosaic在最后 10 轮建议关掉让模型在真实分布上收尾YOLO 默认会在最后 10 轮自动关闭不用手动改。交叉验证方面348 张做 5 折每折约 70 张验证比单次 8:2 更能反映真实水平。做法是把切分脚本的random.seed换成折数循环跑五次训练取 mAP 均值。代价是训练时间翻五倍但 348 张用 nano 版每折也就十几分钟值得。验证时别只看 mAP50小数据集上 mAP50-95 更能暴露框的精度问题。如果 mAP50 很高但 mAP50-95 很低说明框大致对但不够紧回去检查标注的边界框选是否够贴边。另外把预测结果和原图叠在一起看几张比看数字更直观——我见过 mAP 0.9 但框全偏到鸭子屁股上的情况数字会骗人图不会。从那以后我每次拿到新数据集都强制先跑一遍「抽查 xml 坐标 → 转换校验 → 切分查交集 → 训 10 轮看 loss」这四步确认链路干净再上正式训练。这份鸭子数据集在这四步里表现算省心的348 张、双格式、单类别适合拿来把流程走顺。希望帮到你。本文还有配套的精品资源点击获取