
简介面向猪只检测任务的高质量图像数据集同时提供VOC与YOLO两种主流标注格式适合计算机视觉初学者、目标检测算法工程师以及农业智能化项目开发者使用。压缩包内共装载860个文件包含286张原始JPG图像、286个XML标注文件与288个TXT标注文件整体体积约110.58MB文件命名与图像一一对应组织结构清晰可直接导入YOLO、Faster R-CNN等常见检测框架。数据集使用labelImg工具标注类别为单一的Pig共计362个矩形目标框框位准确、边界贴合目标统一规范便于训练时读取。作者也特别说明该数据集不保证模型训练或权重文件的最终精度但标注过程经过合理校验数据质量可靠。目前已有184人学习借助这套资源可快速搭建猪只检测基准实验省去从零开始收集图片和制作标注的繁琐步骤适合用于算法比较、课程设计以及模型效果验证。1. 为什么我建议你直接拿这份猪数据集跑通检测流程做目标检测的同行应该都有这种体验模型结构、训练脚本都调通了最后卡在数据集上。要么是公开数据集类别太杂、背景太乱要么是标注格式五花八门还得写半天转换脚本。这份动物数据集只有 286 张猪的图像VOC 格式的 xml 和 YOLO 格式的 txt 都齐全总共标注了 362 个猪的矩形框类别就是单一的 Pig。它的价值不在数量而在于「单类别、高纯度、双格式齐全」非常适合用来验证数据加载管线、跑通 YOLOv8 或 Faster R-CNN 的训练流程也能用来做迁移学习的起点。对于刚接触检测的初学者或者需要快速做算法验证的工程师这套数据能省掉格式转换和类别筛选的脏活直接进入训练环节。2. VOC 与 YOLO 标注格式的差异及数据组织方式拿到压缩包后第一件事不是解压就跑而是先搞明白里面目录结构和两种标注文件的关系。这个数据集里没有分割路径的 txt只有 jpg 图片、VOC 格式的 xml 文件和 YOLO 格式的 txt 文件。这种设计其实是刻意为之xml 保留完整物体信息便于用 labelImg 继续编辑或转成 COCOtxt 是 YOLO 系列训练直接读取的格式省去在线转换的开销。2.1 目录结构与文件命名规则解压后你会看到类似下面的文件排列dataset_root/ ├── firc_Pig_6.jpg ├── firc_Pig_23.jpg ├── firc_Pig_92.jpg ├── firc_Pig_113.jpg ├── ... ├── firc_Pig_6.xml ├── firc_Pig_23.xml ├── ... ├── firc_Pig_6.txt ├── firc_Pig_23.txt └── ...图片、xml、txt 三者同名同前缀只是扩展名不同。命名里包含的firc_Pig前缀没有特殊含义可以理解为采集来源或批次的标识。在写数据加载脚本时我一般直接按文件名 stem 来关联三种文件而不是依赖目录分类因为这样对后续按比例划分训练集和验证集更省事。提示不要在 Windows 资源管理器里直接改文件名。如果你重命名了 jpg对应的 xml 和 txt 不会自动跟随会导致标注错位。批量重命名要用 Python 脚本同步处理。2.2 VOC 格式内的关键字段解析随意打开一个 xml 文件内容结构如下annotation folderdataset/folder filenamefirc_Pig_113.jpg/filename size width640/width height480/height depth3/depth /size object namePig/name bndbox xmin120/xmin ymin80/ymin xmax340/xmax ymax260/ymax /bndbox /object /annotation这里最关键的是bndbox里的四个值它们表示矩形框的左上角和右下角像素坐标。坐标是绝对像素值基于size中声明的图像宽高。在训练时如果要用 Faster R-CNN 或 SSD 这类框架通常直接读取 xml 并生成 VOC 数据集类如果要用 YOLO则要先把绝对坐标归一化。这个 xml 中每个object对应一个猪的实例数据集里一张图最多可能出现多个object总计 362 个框意味着平均每张图 1.27 个目标分布相对稀疏适合做单类别的 baseline 测试。2.3 YOLO 格式的归一化坐标与类别索引YOLO 格式的 txt 文件每一行代表一个目标格式为class_index x_center_norm y_center_norm width_norm height_norm比如某一行是0 0.453125 0.354167 0.343750 0.416667这里第一个数字0是类别编号因为只有 Pig 一个类别类别列表[Pig]对应的索引就是 0。后四个数字分别是目标框中心点的 x、y 坐标以及框的宽、高全部除以图像宽高做了归一化取值范围在 0 到 1 之间。坐标原点在图像左上角。从 VOC 的绝对坐标转换为 YOLO 格式有个常用脚本片段import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_path, out_txt_path, class_list): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_list: continue cls_id class_list.index(name) bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.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}) with open(out_txt_path, w) as f: f.write(\n.join(lines)) class_list [Pig] voc_to_yolo(firc_Pig_113.xml, firc_Pig_113.txt, class_list)这个脚本的关键逻辑是先从 xml 的size节点拿到图像宽高再对每个object计算归一化后的中心坐标和宽高。注意xmax和xmin必须用同一张图的宽度进行归一化不能混用不同的尺度。如果你的训练框架内部已经支持 VOC 格式就不需要提前转换但如果你要同时做数据增强和在线裁剪直接用 YOLO 格式 txt 会更省心。提示这份数据集提供的 txt 文件已经是归一化好的不需要你再转一遍。上面的脚本只用于你后续自己标注新数据时导出 VOC 再转 YOLO 的情况。3. 基于 YOLOv8 训练单类别猪检测模型数据格式确认无误后就可以开始训练了。我会用 YOLOv8 作为示例因为它对单类别的支持非常友好命令行工具也足够简洁适合快速验证数据质量。3.1 准备 YOLO 格式的数据集配置文件YOLOv8 训练需要先准备一个 data.yaml 文件告诉它图片路径、标签路径和类别名。配置文件写法如下# pig_dataset.yaml path: ./dataset_root # 数据集根目录 train: images/train # 训练图片相对路径 val: images/val # 验证图片相对路径 nc: 1 names: [Pig]由于压缩包内所有图片都在同一层目录我一般会写个脚本按 8:2 的比例划分训练集和验证集并把图片与对应的 txt 文件一起移动到images/train、images/val以及labels/train、labels/val目录。目录结构如下dataset_root/ ├── images/ │ ├── train/ │ │ ├── firc_Pig_6.jpg │ │ └── ... │ └── val/ │ └── ... └── labels/ ├── train/ │ ├── firc_Pig_6.txt │ └── ... └── val/ └── ...注意 YOLOv8 要求图片和标签的目录结构一一对应train 的图片对应 train 的标签val 同理。划分时不能打乱文件对否则训练时标签错位会出现大量WARNING: ignored corrupt image信息。3.2 执行训练命令与关键参数说明数据准备完毕后执行下面的命令开始训练yolo train datapig_dataset.yaml modelyolov8s.pt epochs100 batch16 imgsz640 device0参数说明modelyolov8s.pt使用 YOLOv8s 预训练权重作为初始权重由于数据集只有 286 张图迁移学习能明显加快收敛也避免从头训练带来的过拟合。batch16如果显存不够可以改成 8 或 4。这个数据集图像分辨率不明建议先用imgsz640训练如果发现大量小目标检测不到再调高到 960。epochs100单类别且数据量小100 轮已经足够实测通常在 30 到 50 轮时 mAP50 就能达到 0.95 以上。device0指定使用第一块 GPU。没有 GPU 时改为devicecpu但训练速度会慢数倍。训练过程中终端会打印每个 epoch 的 loss、precision、recall 和 mAP50/mAP50-95。如果 loss 从初始的 2 到 3 快速下降到 0.8 以下说明数据标注质量没问题如果 loss 迟迟不降重点检查 txt 中是否有超出 0 到 1 范围的坐标值。3.3 验证标签与图像的匹配情况训练前最好跑一次数据校验YOLOv8 没有内置直接命令但我通常写个小脚本检查每个 txt 文件里是否有越界坐标import os label_dir labels/train for f in os.listdir(label_dir): path os.path.join(label_dir, f) with open(path) as fp: for line in fp: parts line.strip().split() if len(parts) ! 5: print(f格式错误: {path}: {line}) continue cls, xc, yc, w, h (parts[0], float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4])) if not (0 xc 1 and 0 yc 1 and 0 w 1 and 0 h 1): print(f坐标越界: {path}: {line})这段代码逐行读取 YOLO 标签检查类别索引是否为 0以及归一化坐标是否在合法范围内。如果发现 xc 或 yc 等于 0 或 1很可能是框贴边造成的虽然 YOLOv8 能容忍但建议裁剪掉边界框超出的那部分像素以免影响 loss 计算。4. 数据增强与训练细节调优只有 286 张图直接训练容易过拟合。我建议在训练阶段开启数据增强YOLOv8 默认开启马赛克增强但对于猪这种单一类别目标马赛克增强可能会把猪切成碎片导致学习到的特征不稳定。这里有两种处理思路。4.1 控制增强策略避免过度扰动在 ultralytics 的配置中可以通过hsv_h、hsv_s、degrees等参数控制增强强度。为了不让猪的纹理和轮廓失真我一般会把水平翻转概率设为 0.5旋转角度控制在 10 度以内具体训练命令是yolo train datapig_dataset.yaml modelyolov8s.pt epochs80 batch16 imgsz640 \ flipud0.0 fliplr0.5 degrees10 translate0.1 scale0.3其中flipud0.0禁止上下翻转因为猪很少倒立出现translate0.1允许少量平移模拟猪在不同画面位置的情况。增强策略设置过强时训练集 loss 会下降得很慢而且验证集 mAP 会出现明显抖动。如果遇到这种问题先关闭增强对比一下再用逐步增加的策略找平衡点。4.2 从单类别数据的 loss 曲线判断问题训练结束后在runs/detect/train目录下能看到results.png和results.csv。关注train/box_loss和val/box_loss两条曲线。正常情况下两者都逐渐下降并趋于平缓。如果 val loss 在后期反弹说明过拟合需要增加权重衰减或使用更大的预训练模型正则。这里有一个保守的配置方案参数建议值说明optimizerAdamW 或 SGDAdamW 收敛快SGD 泛化稍好weight_decay0.0005防止过拟合warmup_epochs3小数据集预热不需要太久close_mosaic10最后 10 轮关闭马赛克稳定收敛patience30如果验证集 30 轮没提升就早停close_mosaic10是 YOLOv8 提供的参数意思是训练最后 10 个 epoch 自动关闭马赛克增强让模型在干净的样本上微调。这种策略在小型数据集上效果非常明显推荐使用。5. 模型推理与猪检测结果验证训练完成并不是终点还要跑一遍推理确认模型在实际图片上的表现。尤其是这种单类别小数据集训练 mAP 高不能代表泛化能力好需要用没参与训练的图像做可视化验证。5.1 使用训练好的权重进行推理运行推理命令yolo predict modelruns/detect/train/weights/best.pt sourcedataset_root/images/val/ save_txtTrue save_confTrue这条命令会读取训练阶段保存的best.pt权重对验证集所有图片执行目标检测。save_txtTrue会把预测结果保存为 txt 文件格式与训练标签一致save_confTrue会在保存的 txt 中追加置信度分数。预测输出的 txt 文件内每一行代表一个检测到的猪格式是0 0.4289 0.3278 0.3521 0.4104 0.9234最后一位 0.9234 就是置信度。检查这些预测值时重点关注两点一是置信度低于 0.5 的检测框是否占比较高如果是说明模型对某些姿态或光照条件下的猪识别不稳定二是同一张图里检测框是否重叠严重重叠过多可能需要调低 NMS 阈值在推理命令中加入iou0.5来调节。5.2 目标计数与位置分布统计做完检测后可以用一个简单脚本统计每张图的猪数量和平均框置信度用于评估模型是否偏向漏检或误检import os pred_dir runs/detect/predict/labels total_dets 0 low_conf_dets 0 for f in os.listdir(pred_dir): with open(os.path.join(pred_dir, f)) as fp: for line in fp: parts line.strip().split() total_dets 1 if float(parts[-1]) 0.5: low_conf_dets 1 print(f总共检测 {total_dets} 个目标其中低置信度 {low_conf_dets} 个)这个统计能帮你判断模型是否对某类特殊图像失效。如果低置信度目标集中在某个子集把那几张图像挑出来分析是不是遮挡严重或猪只占画面比例太小。对这些失败样本最常见的手段是扩充训练集中的相似角度或者把imgsz从 640 提升到 768让模型看到更多细节同时调整conf阈值到 0.25 来缓解漏检。5.3 用 mAP 和混淆矩阵做最终评估如果需要更正式的评估运行yolo val modelruns/detect/train/weights/best.pt datapig_dataset.yaml输出结果里会包含每个类别的 precision、recall、mAP50、mAP50-95。由于数据集只有 Pig 一个类别混淆矩阵会比较简单重点看 recall 是否达到 0.95 以上。如果 recall 偏低说明存在漏检如果 precision 偏低则说明存在误检。小数据集常见问题是最终 mAP 在 0.93 到 0.98 之间浮动这是正常的不必为了追求极致的 0.99 去过度调参反而可能导致泛化能力下降。6. 用数据校验脚本排查标注边界与类别遗漏最后分享一个实用技巧用于排查这份数据集在交给别人复用时可能出现的标注边界问题。很多标注工具生成的框如果紧贴图像边缘转换到 YOLO 格式时坐标会恰好等于 0 或 1这会导致训练时 OpenCV 读取边界框时越界。针对这个数据集我编写了一个校验脚本也适合你自己后续标注的数据。import os from PIL import Image def check_all_labels(img_dir, label_dir): for img_name in os.listdir(img_dir): stem os.path.splitext(img_name)[0] lbl_path os.path.join(label_dir, stem .txt) if not os.path.exists(lbl_path): print(f缺失标签: {stem}) continue with Image.open(os.path.join(img_dir, img_name)) as img: w, h img.size with open(lbl_path) as fp: for line in fp: parts line.strip().split() if len(parts) ! 5: print(f字段数量错误: {stem}) continue xc, yc, bw, bh map(float, parts[1:]) # 计算绝对像素值判断是否超出图像边界 xmin (xc - bw / 2) * w xmax (xc bw / 2) * w ymin (yc - bh / 2) * h ymax (yc bh / 2) * h if xmin -1 or ymin -1 or xmax w 1 or ymax h 1: print(f边界越界: {stem}: {parts}) check_all_labels(images/train, labels/train)这段脚本把 YOLO 归一化坐标反算回绝对像素坐标并与图像的实际宽高对比。允许 1 像素的容差避免浮点误差导致的误报。如果检查发现越界框直接编辑 txt 中对应行把越界部分裁剪到图像范围内即可。这个操作看似简单却能避免训练时一条未知错误导致整个 epoch 中断。对于这份猪数据集本身你还可以做一个更细致的类别分布检查统计每张图片中 pig 框的数量找出包含 3 个以上 pig 的样本单独把它们挑选出来扩充到验证集中用来检验模型在多目标场景下的表现。这种针对数据分布的额外检查往往比继续调参更能提升模型的实际可用性。本文还有配套的精品资源点击获取