ARTICLE DETAIL

资讯详情

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

630张鸭子数据集:VOC与YOLO双格式小样本目标检测实战

630张鸭子数据集:VOC与YOLO双格式小样本目标检测实战 简介这是一份面向目标检测初学者与算法工程师的鸭子识别数据集采用Pascal VOC与YOLO双格式标注可直接用于训练和验证单类别检测模型省去自行采集与标注的成本。压缩包共1892个文件包含630张jpg原图、630个VOC格式xml标注文件、630个yolo格式txt标签文件另有少量说明文本整体约199.6MB图片与标注一一对应方便在YOLO、Faster R-CNN等框架间快速切换。标注由labelImg完成类别仅Duck一类共1149个矩形框平均每张图约1.8个目标适合做小样本单类检测的入门实验或迁移学习预训练。目前已有217人学习下载可作为课程设计、毕业项目或算法验证的现成数据基础帮助读者把精力集中在模型调参与效果对比上。1. 630 张鸭子数据集小样本 VOCYOLO 双格式到底能干什么手上只有几百张图还想训一个能用的检测模型这是很多做垂直场景的人绕不开的处境。这个鸭子数据集就是典型样本630 张图、1 个类别duck、同时给了 VOC 格式和 YOLO 格式。它解决的不是「通用大模型」问题而是让你在半天内跑通一条从标注文件到可推理权重的完整链路验证自己的训练脚本、增强策略和部署流程有没有问题。适合两类人一是刚入门目标检测、想找一个类别干净、标注完整的小数据集练手的人二是手里有真实业务图但还没标完想先用一个结构一致的小集把 pipeline 调通的人。630 张不算多但 1 类别意味着类别不平衡、背景干扰这些麻烦事基本没有你能把注意力放在格式转换、训练参数和验证指标上而不是清洗脏数据。2. VOC 与 YOLO 双格式先搞懂两套标注的坐标系差异2.1 VOC 的 XML 结构与字段含义VOC 格式每张图对应一个同名 XML核心信息在object节点里。一个典型的鸭子标注长这样annotation folderduck/folder filenameduck_001.jpg/filename size width640/width height480/height depth3/depth /size object nameduck/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin112/xmin ymin86/ymin xmax398/xmax ymax402/ymax /bndbox /object /annotationxmin/ymin/xmax/ymax是绝对像素坐标原点在左上角。difficult字段在评估时决定是否跳过该目标truncated表示目标是否被截断。很多转换脚本翻车就翻在没读size里的宽高直接拿坐标归一化结果框全飘了。VOC 的好处是可读性强、工具链老牌labelImg 默认就存这个坏处是文件多、解析慢630 张就是 630 个 XML。2.2 YOLO 的 txt 归一化坐标与类别索引YOLO 格式每张图对应一个同名 txt每行一个目标格式是0 0.3984375 0.5083333 0.446875 0.6583333五个字段依次是class_id center_x center_y width height全部是相对图像宽高的归一化值范围 0~1。上面这行对应 VOC 里那个框中心 x (112398)/2/640 ≈ 0.398中心 y (86402)/2/480 ≈ 0.508宽 (398-112)/640 ≈ 0.447高 (402-86)/480 ≈ 0.658。注意 YOLO 没有difficult概念类别从 0 开始编号1 类别时永远是 0。还有一个隐藏坑YOLO 要求每张图都有对应 txt负样本没有目标的图要留一个空 txt否则训练时该图会被当成损坏数据跳过。2.3 两套格式的对应关系与转换时机维度VOCYOLO坐标绝对像素归一化 0~1存储每图一个 XML每图一个 txt类别字符串 name整数 id负样本无 object 节点空 txt常用工具labelImg、mmdetectionultralytics、darknet选哪套取决于你的训练框架。用 ultralytics 系YOLOv5/v8/v11直接吃 YOLO 格式用 mmdetection、Detectron2 走 VOC 或 COCO。这个数据集两套都给省掉了自己转的麻烦但你要清楚它们不是简单改后缀坐标语义完全不同。常见做法是训练用 YOLO 格式评估和可视化用 VOC 格式回查原始框两边对不上时优先信 VOC因为它是绝对坐标肉眼可验。3. 从 630 张图到可训练集目录组织与最小训练命令3.1 目录结构怎么摆才不报错ultralytics 对目录结构有硬性约定摆错了会直接报No labels found。推荐这样组织duck_dataset/ ├── images/ │ ├── train/ # 约 500 张 │ └── val/ # 约 130 张 ├── labels/ │ ├── train/ # 与 train 图片同名的 txt │ └── val/ └── duck.yaml图片和标签必须同名不同后缀且 images 和 labels 的目录层级要镜像对应。630 张按 8:2 切训练 504 张、验证 126 张1 类别下这个量级验证集够看趋势但别指望指标很稳。切分时注意同一只鸭子的连拍图不要跨 train/val否则验证指标虚高这是小数据集最隐蔽的泄漏。3.2 duck.yaml 的四个必填字段path: /home/user/duck_dataset train: images/train val: images/val nc: 1 names: 0: duckpath是数据集根目录train/val是相对 path 的子路径。nc是类别数1 类别就写 1写错会直接维度不匹配。names是 id 到类名的映射顺序必须和 txt 里的 class_id 一致。很多人从别处抄 yaml 忘了改nc训练能启动但 loss 一直不降回头查半天才发现类别数对不上。3.3 一条命令跑通首次训练yolo detect train \ dataduck_dataset/duck.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ projectruns/duck \ nameexp1modelyolov8n.pt用预训练权重小数据集必须靠迁移学习从零训 630 张基本学不出东西。imgsz640是输入分辨率和标注时的图像尺寸不必一致框架会自己缩放。batch16在 8G 显存上跑 640 分辨率比较稳显存不够就降到 8 并开ampTrue。epochs100对 1 类别小集通常够收敛看results.csv里 mAP50 连续 20 轮不涨就可以停。训练完权重在runs/duck/exp1/weights/best.pt。3.4 验证与推理确认模型真的学到了鸭子yolo detect val modelruns/duck/exp1/weights/best.pt dataduck_dataset/duck.yaml yolo detect predict modelruns/duck/exp1/weights/best.pt sourcetest_imgs/ saveTrueval会输出 mAP50、mAP50-95、precision、recall。1 类别小集上 mAP50 到 0.85 以上算正常低于 0.6 先查标注有没有框错、类别 id 有没有写乱。predict的saveTrue会把画框结果存到runs/detect/predict肉眼过一遍比看数字更靠谱。如果框位置整体偏移八成是训练时图像被 letterbox 填充而你没意识到推理时又用了原图比例。4. 小样本训练的避坑清单630 张最容易翻车的五个地方4.1 现象loss 正常下降但 mAP 始终为 0原因通常是验证集标签路径没对上框架读到了图但没读到对应 txt把所有预测都当误检。解决检查labels/val下 txt 数量和images/val下图片数量是否一致文件名不含后缀是否逐一对应。用ls images/val | wc -l和ls labels/val | wc -l对比数字不等就是这里的问题。4.2 现象训练报Label class X is out of bounds原因txt 里的 class_id 超过了nc-1。1 类别时合法 id 只有 0如果转换脚本从 1 开始编号就会报这个。解决全局搜一遍 txt 第一列确认最大值是 0。批量修正可以用find labels -name *.txt -exec sed -i s/^1 /0 / {} \;执行前先备份sed 改错不可逆。4.3 现象框位置整体偏移或缩放原因VOC 转 YOLO 时用了错误的宽高做归一化比如拿size里的值去归一化另一张图的坐标或者图像被预处理过裁剪、旋转但标注没同步。解决随机抽 5 张图用脚本把 YOLO 坐标反算回像素和 VOC 的 xmin/ymin 对比误差超过 2 像素就要查转换逻辑。归一化公式是(x - xmin) / width别把 xmax 当宽用。4.4 现象验证指标高得离谱实际推理一塌糊涂原因train/val 切分时同一场景或连拍图泄漏模型在验证集上等于见过答案。解决按拍摄批次或时间切分而不是随机切。630 张如果来自几十段视频抽帧按视频段切保证验证集里的鸭子和训练集不是同一批。这个坑在小数据集上比过拟合更常见。4.5 现象显存溢出或训练中途被杀原因batch或imgsz设太大或者workers开太多导致内存爆。解决先把batch降到 8、imgsz降到 416 跑通再逐步往上加。workers4在多数机器上够用设 8 以上反而可能因为数据加载竞争变慢。用nvidia-smi盯显存留 1G 余量给系统。5. 把 630 张用到极致增强策略与指标验证的进阶技巧小数据集的瓶颈从来不是模型结构而是数据多样性。630 张如果都是相似角度、相似光照模型学到的就是「这只鸭子在这个背景下长这样」换个场景立刻崩。我一般会先做一轮离线增强把训练集扩到 3~5 倍再开在线增强。离线增强用 albumentations 做随机裁剪、亮度对比度扰动、轻微旋转和水平翻转注意翻转后要同步改标注坐标水平翻转的 x 坐标变换是new_x 1 - x中心点和宽不变但 xmin/xmax 要互换。import albumentations as A import cv2, os transform A.Compose([ A.HorizontalFlip(p0.5), A.RandomBrightnessContrast(p0.4), A.Rotate(limit10, p0.3), A.RandomCrop(width512, height512, p0.3), ], bbox_paramsA.BboxParams(formatyolo, label_fields[class_labels])) img cv2.imread(duck_001.jpg) with open(duck_001.txt) as f: boxes [list(map(float, line.split())) for line in f] bboxes [b[1:] for b in boxes] labels [int(b[0]) for b in boxes] out transform(imageimg, bboxesbboxes, class_labelslabels) # out[bboxes] 已是增强后的归一化坐标直接写回 txtformatyolo告诉 albumentations 输入是归一化坐标它会自动处理翻转和裁剪后的坐标变换。label_fields保证类别 id 跟着框走。离线增强后训练集从 504 张扩到 2000 张左右再跑同样的训练命令mAP50 通常能涨 5~10 个点。在线增强则靠 ultralytics 自带的hsv_h/hsv_s/hsv_v/degrees/translate/scale/fliplr参数默认值对鸭子这种目标偏保守可以把scale调到 0.5、translate调到 0.2让模型见更多位置变化。验证阶段别只看 mAP。1 类别小集上recall 比 precision 更值得盯漏检一只鸭子比多框一个背景更影响业务。如果 recall 低先降置信度阈值看曲线再查是不是小目标太多、imgsz不够。630 张里如果有大量远距离小鸭子把imgsz提到 960 比换模型更有效。最后留 20 张完全不参与训练和验证的图做盲测跑一遍predict肉眼看这是唯一能暴露「指标好看但实际不能用」的后悔药。我自己的习惯是每次改完增强或参数先跑 10 轮看 loss 曲线形状形状不对就别浪费 100 轮的电。希望帮到你。本文还有配套的精品资源点击获取
返回列表