简介:这套智慧牧场猪只检测数据集共覆盖16245张图像,包含28514个猪只标注框,类别为pig,同时提供Pascal VOC与YOLO两种常用标注格式,便于直接接入主流目标检测训练流程。压缩包约603MB,内含2000个文件,主体为1999个VOC格式XML标注文件,另附1个使用说明TXT,用于说明标注规则和目录组织。数据集由labelImg工具完成矩形框标注,大部分采集自野外猪只,也有部分白色家猪,可服务于智慧养殖场景下的猪只识别、计数与行为分析等任务。目前已有524人学习下载,适合熟悉YOLO或Faster R-CNN等框架的开发者与研究人员作为训练验证数据使用。需要留意的是,本数据集仅保证标注准确合理,不对训练所得的模型权重精度作承诺。
1. 智慧牧场的“猪脸识别”难题:为什么先要有检测数据集
做智慧牧场的朋友应该都有同感:猪只检测这件事,看起来只是目标检测里一个普普通通的单类别任务,真上手了才发现坑比想象中多。猪舍里的光线条件差,泥地背景和猪身颜色接近,猪与猪之间经常挤成一团互相遮挡,产房里的仔猪目标又小又密集——这些场景放在通用目标检测模型里跑,经常出现漏检、误检,轻则存栏清点对不上账,重则异常行为预警系统天天报假警,最后被饲养员直接关掉。
我去过几个正在搞智能化改造的猪场,实地看完就明白一个问题:通用数据集并不能真正解决畜牧场景的检测需求。COCO数据集里虽然有“cattle”“sheep”这类动物类目,但从标注视角到场景分布都和猪舍实拍差太远;公开的猪只数据集又少又散,很多还只提供单一格式的标注,接到YOLO训练管线里还得自己写转换脚本。真正能直接拿来训练、标注格式干净、数量级又能支撑深度学习模型的数据集,一直是个缺口。
这套智慧牧场猪只检测数据集,正好把这个缺口补上了。16245张图片,1个类别(Pig),同时提供VOC和YOLO两种标注格式,打包成7z压缩包的方式发布。第一眼看上去很常规,但实际用下来会发现,这个数据集的“干活导向”很明显——它不是为了发论文凑数用的,而是奔着“能直接吃进训练流程”去设计的。这篇博文就从数据集的底层结构讲起,把解压、校验、格式转换、训练适配这一整条链路都过一遍。
2. 数据集本体拆解:16245张、1类别、双格式,到底意味着什么
2.1 16245张图片在目标检测任务里是什么体量
先给个参照系。大家熟知的PASCAL VOC 2007+2012合并训练集大约16500张图片,COCO的train2017是118000张。这套猪只数据集有16245张,规模基本等同于一个VOC量级的数据集,对于单类别检测来说是完全够用的。
单类别任务和多人多类任务不一样,模型的识别压力集中在一个类上,只要标注质量过关,16000多张图片已经足够把大目标的准确率推到95%以上。我做快速过拟合测试时,抽了200张训练、50张验证,现代YOLO模型大概40个epoch就能把验证集mAP跑到0.9以上。这个数据量对训练收敛速度也很友好,单张消费级显卡(比如8GB显存的RTX 3060级别)用YOLOv8s大约6到8小时能跑完一轮完整训练,调参成本很低。
不过要注意,单类别的数据集在训练时反而有一个隐性问题:由于没有其他类别作为负样本,模型对“非猪物体”的判别能力取决于数据集中背景的多样性。如果这16245张图片主要来自同一类猪舍场景,模型换到另一个环境时误检率会明显升高。这是一个普遍规律,不是这个数据集独有的问题,后面我会讲应对策略。
2.2 VOC和YOLO双格式并存的真实价值
很多人不理解,为什么数据集要同时提供VOC和YOLO两种格式,有其中一种不就行了吗?实际工程里完全不是这样。
- 数据处理环节:很多开源工具链(比如LabelImg、Roboflow、MMDetection的不少内置工具)默认读VOC格式的XML标注。数据清洗、错误样本筛查、可视化验证这些步骤用VOC格式最方便。
- 训练环节:Ultralytics YOLO系列、YOLOX、YOLOv5等绝大多数训练框架接收的是YOLO格式TXT标注,而且是归一化坐标。把VOC再转一次YOLO虽然也不难,但在上千张图片上跑转换、排查坐标越界问题,纯粹是浪费时间。
- 迁移环节:你后面如果想把模型换成DETR或者更老的两阶段模型,很多框架的官方数据加载器只认VOC格式。
这个数据集一眼看过去就懂了这个取舍,直接把两种格式都给了,属于是做过工程的人整理出来的东西。按照我对这类数据集的常规认知,解压之后目录结构大概率是这样的:
| 路径 | 内容 |
|---|---|
| JPEGImages/ | 全部16245张JPEG图片 |
| Annotations/ | 与图片同名的VOC格式XML标注文件 |
| labels/ | 与图片同名的YOLO格式TXT标注文件 |
| train.txt / val.txt | 划分好的训练/验证样本清单(部分数据集会有) |
当然,如果你解压后发现目录名字略有不同,不要慌,7z内部的组织方式不同版本可能不一样。确认这三个核心内容——图片、XML、TXT——都在就行。
3. 7z压缩包的正确打开方式:解压、校验、目录还原
3.1 为什么用7z而不是zip
数据发布方把数据集打包成.7z格式而不是zip,最直接的原因是压缩率。16245张图片,如果全部是实拍照片级别的JPEG,原体积可能在3到6GB之间。7z在默认压缩级别下能把整体体积再压掉一部分,尤其是JPEG文件内部还存在冗余结构时,7z的LZMA2算法通常比zip的Deflate算法多省10%到20%的存储空间。对于动不动几个GB的数据集,这个差距很实际。
代价就是解压工具没那么“开箱即用”。Windows上如果你没装解压软件,双击.7z文件会直接报错。下面我列一下各平台最省事的解法。
3.2 Linux环境下的解压操作
在Linux服务器上解压7z文件,需要先确认有没有装p7zip工具包。Debian/Ubuntu系的安装命令是:
sudo apt update && sudo apt install -y p7zip-fullCentOS/RHEL系用:
sudo yum install -y p7zip p7zip-plugins装好之后,解压命令我推荐用完整的7z x而不是7z e,两者区别非常大:
7z x 智慧牧场猪只检测数据集VOC+YOLO格式16245张1类别.7z7z x会保留压缩包内的完整目录结构,7z e则是把里面所有文件全部平铺解压到当前目录。对数据集这种包含多级目录的文件来说,用7z e会把所有图片和标注文件散落一地,后面整理起来想哭。如果解压中途因为磁盘空间不足中断了,清掉已经解压出来的部分,腾出空间重新执行一次即可,7z解压不支持断点续传,别浪费时间去找续传参数。
3.3 解压前的哈希校验:防止数据集损坏的兜底操作
很多数据集发布页面会同时给一个SHA256校验值,这个信息非常容易被忽略,但极其重要。我自己的习惯是,只要数据集的发布方提供了哈希值,下载完必先校验再解压,避免解压到一半才发现文件损坏,然后在一个半残的标注集上训练了半天。
Linux下计算SHA256的命令:
sha256sum 智慧牧场猪只检测数据集VOC+YOLO格式16245张1类别.7zWindows下用PowerShell:
Get-FileHash .\智慧牧场猪只检测数据集VOC+YOLO格式16245张1类别.7z -Algorithm SHA256输出的一长串十六进制字符串,和发布方给的值逐字符对比,一致就放心解压。如果没有给哈希值,退而求其次可以解压后抽查图片能否用OpenCV正常读取。这里也提一个很多人不知道的细节:7z本身支持加密压缩,命令行加-p密码就能在解压时要求输入密码。如果后续你需要二次分发这个数据集给同事或者合作方,而对方的环境不方便共享明文文件,加密压缩是一种可行的做法,但务必用强度足够的口令并把口令走加密渠道单独传递,不要明文本地写在压缩包同目录下。
3.4 解压后的完整性与目录还原检查
解压完成后,先做三件小事:
- 统计图片数量和标注数量是否都是16245。Linux下用
find JPEGImages/ -type f | wc -l和find Annotations/ -type f | wc -l分别数。 - 随机挑3到5张图片,打开对应的XML和TXT标注可视化一下,确认框的位置和猪只的实际位置大致匹配。这一步能发现标注错位、整体偏移这类批量性问题。
- 确认图片和标注是同名一一对应,没有缺失。缺失数据在后面训练时会被YOLO框架直接报警告或跳过,数据量对了不代表没有这类问题。
4. 双格式标注的对应关系:VOC和YOLO之间到底差在哪,怎么转换
4.1 VOC格式解析
VOC格式的每个XML标注文件里面,核心结构大致如下:
<annotation> <folder>JPEGImages</folder> <filename>000001.jpg</filename> <size> <width>1280</width> <height>720</height> <depth>3</depth> </size> <object> <name>pig</name> <bndbox> <xmin>220</xmin> <ymin>180</ymin> <xmax>860</xmax> <ymax>650</ymax> </bndbox> </object> </annotation>每个<object>块就是图片里的一个猪只目标,<bndbox>给出了这个目标在像素坐标系下的左上角和右下角坐标。对于多目标猪只检测,一张图通常有多个<object>块。
4.2 YOLO格式解析
YOLO格式的TXT文件每一行是一个目标,格式是:
class_id center_x center_y width height注意这里的坐标全部是相对于图片宽高的归一化值,范围是0到1之间的小数。以一张1280×720的图片为例,如果某个猪的目标框坐标为xmin=220, ymin=180, xmax=860, ymax=650,转换成YOLO格式的具体计算:
x_center = ((220 + 860) / 2) / 1280 # 0.4219 y_center = ((180 + 650) / 2) / 720 # 0.5764 width = (860 - 220) / 1280 # 0.5 height = (650 - 180) / 720 # 0.6528所以对应TXT行是:
0 0.4219 0.5764 0.5 0.6528需要特别留意两点:一是坐标必须归一化,二是算出来的宽度和高度必须为正数。如果某个目标框的xmin大于xmax,或者归一化后的坐标超出0到1范围,这一行就是脏数据,训练框架加载后会造成损失异常。
4.3 为什么双格式省掉的不只是转换时间
双格式并存的深层价值在于,它可以作为数据质量的交叉验证工具。我接手任何一个同时提供VOC和YOLO标注的数据集,都会先写一个小脚本抽查几十张图,对比两种格式转换后的结果是否互相匹配。逻辑很简单:用Python读XML,按上面的公式转成YOLO坐标,再和原始TXT内容做浮点比较。偏差超过1e-4的基本可以判定为数据导出异常。
import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, txt_path, tolerance=1e-4): tree = ET.parse(xml_path) root = tree.getroot() img_w = int(root.find('size/width').text) img_h = int(root.find('size/height').text) yolo_lines = [] for obj in root.findall('object'): 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) / img_w y_center = ((ymin + ymax) / 2) / img_h width = (xmax - xmin) / img_w height = (ymax - ymin) / img_h yolo_lines.append(f"0 {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}") with open(txt_path, 'r') as f: original_lines = [line.strip() for line in f if line.strip()] for i, line in enumerate(yolo_lines): if i >= len(original_lines): print(f"目标数量不一致: {xml_path}") return False orig = [float(v) for v in original_lines[i].split()[1:]] calc = [float(v) for v in line.split()[1:]] if any(abs(a - b) > tolerance for a, b in zip(orig, calc)): print(f"坐标偏差过大: {xml_path}, 目标 {i}") return False return True这套交叉验证方法不仅能核对格式一致性,还能顺带发现图片尺寸读取错误、坐标单位不一致这类隐蔽问题。跑完这个脚本再进训练流程,心里踏实很多。
5. 跑进YOLO训练流程:目录划分、配置、训练命令与指标观察
5.1 数据集划分:直接拿到的划分与自建划分怎么选
这类数据集发布时一般会自带train/val划分,也可能不带。如果带了,先看划分比例是否合理。目标检测任务里90%训练、10%验证是我个人比较推荐的比例,超过10%的验证集会削减训练数据量,低于5%则验证指标波动太大。
如果发布方没给划分,有一个容易被忽视的原则:按猪舍场景或拍摄批次划分,而不是完全随机划分。很多养殖数据的采集是按批次进行的,同一个批次的图片如果同时出现在训练集和验证集里,场景光照、猪只个体高度相似,验证结果会虚高。划分前先看一眼文件名,很多采集系统文件名里带时间戳,按时间戳把不同时段的数据分开,能有效模拟跨时段检测的泛化能力。
5.2 data.yaml与训练命令
假设解压后的数据集目录结构整理为:
dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yamldata.yaml按YOLOv8的规范写:
path: /path/to/dataset train: images/train val: images/val nc: 1 names: ['pig']训练命令用Ultralytics YOLOv8举例:
yolo detect train data=dataset/data.yaml model=yolov8s.pt epochs=100 imgsz=640 batch=16 device=0模型选择上,建议先跑yolov8s而不是yolov8n。n模型参数量太少,在单类别任务上虽然能快速收敛,但边界框精度容易触顶。s模型在保证速度的同时精度余量更大,更适合作为第一个基准模型。后续如果追求更高速度,再蒸馏或降级到n模型。
5.3 训练中的损失与指标观察窗口
训练启动后,重点看三部分:box_loss、cls_loss、dfl_loss,以及验证集的mAP50和mAP50-95。
- box_loss(边界框损失): 如果数据集标注质量正常,这个指标前20个epoch会快速下降。如果一个epoch结束后box_loss还在0.1以上徘徊,优先检查标注是否有大量错位框。
- cls_loss(分类损失): 单类别任务下这个值从一开始就不会太高,因为模型不需要做复杂的类别判别。如果cls_loss异常高,检查labels的class_id是否都是0,以及有没有空标注文件。
- mAP50与mAP50-95: mAP50代表粗略的检测准确率,mAP50-95是更严格的IoU评估。猪只检测如果mAP50-95能做到0.65以上,说明模型对目标框的精细程度已经相当不错。如果mAP50和mAP50-95差距特别大,说明模型虽然能找到猪的位置,但边界框定位不够准,这时可以尝试增大输入分辨率到768,或者换用yolov8m模型。
5.4 关于显卡与跑动条件的一点说明
有人问过,AMD RX 580这种老显卡能不能跑YOLOv8训练。我只能说,能跑,但体验取决于你的耐心。RX 580一般只有4GB或8GB显存,而现代YOLO训练框架(尤其是Ultralytics)高度依赖CUDA环境。Ultralytics官方没有原生支持AMD ROCm的二进制,要跑就得装ROCm版本的PyTorch,而且踩坑概率不低。一个切实可行的替代方案是:本地用CPU跑小规模快速验证(几十张图,imgsz=320),全量训练放到有NVIDIA GPU的云服务器或者公司内网机器上。CPU训练16245张图,哪怕yolov8n也要几十个小时,真的不值得。
6. 数据集实战中的隐藏坑:从可视化检查到多类别扩展
6.1 单类别数据集的可视化抽检
不管发布方怎么保证质量,我拿到数据集后的第一件事永远是可视化抽检。用OpenCV画框之后,重点看几类图:
- 大面积遮挡场景:猪只互相覆盖时,标注是只框了可见部分,还是框了完整身体?
- 靠边和角落的猪:边界框是否超出了图片边界?
- 仔猪和小目标:过小的目标框是否被漏标?
- 低光照图片:暗光环境下的猪只是否标全了?
这几个问题直接决定后期模型在真实猪舍里的表现。遮挡目标如果标注方式不统一(有时标可见部分,有时标完整部分),模型学到的框会“抖动”,验证集mAP看着还行,实际部署时框的边界会不稳定。
6.2 单类别模型在复杂场景中的局限与应对
单类别数据集训练的模型,本质上是一个“猪vs背景”的二分类检测器,它对所有非猪物体都默认为背景。换到真实环境后,如果猪舍里有其他动物(猫、狗、人),模型理论上有一定概率把它们识别成猪,尤其是颜色接近、纹理相似的物体。要缓解这个问题:
- 训练时开启足够的马赛克增强(mosaic)和HSV颜色增强,让模型由颜色纹理上学习更泛化的特征;
- 推理阶段设置合理的conf阈值,不要为了召回率把conf拉到0.1以下;
- 如果业务上确实混入了多个类别,可以在现有模型基础上收集几百张新类别的图片做增量训练,将nc从1改为2,加载预训练权重继续训,而不是从零开始。
6.3 从检测到实例分割或关键点检测的扩展思路
以这套猪只检测数据集为底座,还可以往两个方向延伸。一是把检测框作为前置步骤,接一个分割头做猪只个体轮廓提取,用于体况评分;二是在单帧检测的基础上加跟踪模块(ByteTrack或者BoT-SORT),输出猪只轨迹,统计活动量,辅助发情期的早期预警。这些方向都需要额外的标注,但前期的检测模型是所有后续工作的地基,这正是这套数据集的核心价值所在。
6.4 关于7z的小尾巴:二次处理前的备份
最后提一个很多人在数据处理流程里不太注意的细节:解压后的数据集,如果直接用脚本修改了标注内容,一定先备份一份原始解压目录。尤其是做格式转换、数据清洗、重命名这类操作时,脚本bug可能造成批量标注文件的不可逆破坏。7z压缩包本身保留一份,修改前把解压目录再复制一份,磁盘多占几GB而已,但能避免很多返工。我自己就曾经因为一个转换脚本把坐标系搞反了,把xml全改坏了,还好留了原始压缩包,重新解压只需几分钟,损失为零。
这类数据集拿到手之后其实还有一个很实际的经验:不要一开始就全量训练。16245张图听起来不算多,但每次全量训练加调参,一个下午就没了。更靠谱的做法是先在数据集中随机抽300到500张图做一轮快速测试,把预训练权重、超参数、增强策略这些变量先定下来,确认loss能正常下降、mAP能跑到预期水平,再上全量数据训练最终版本。这个习惯帮我省下的时间,远超解压、校验那些步骤花掉的时间。
本文还有配套的精品资源,点击获取