家禽鸡小鸡检测数据集:2970张VOC+YOLO双格式,从零跑通YOLOv8训练
简介这份资源是面向计算机视觉初学者与目标检测工程实践者的家禽鸡只检测数据集可用于训练和验证鸡类目标识别模型适用于课程设计、算法练手及小型养殖场景的智能监测原型开发。压缩包共约2000个文件以1999个VOC格式xml标注文件和1个说明txt为主另含对应的YOLO格式txt与jpg图片整体约50.18MBxml与txt分别适配Pascal VOC和YOLO两种主流训练流程方便直接接入常见检测框架。数据集共2971张图片标注类别为chicken累计6358个标注框全部由labelImg手工完成标注质量相对可靠。目前已有462人学习下载可作为入门目标检测的实战素材帮助读者快速跑通数据加载、格式转换、模型训练与评估的完整链路并在此基础上尝试数据增强与类别扩展。1. 家禽鸡小鸡检测数据集2970 张 VOCYOLO 双格式到底能干什么养殖场里做雏鸡存活率统计最头疼的不是模型选哪个而是手里根本没有能直接喂给 YOLO 的标注数据。网上公开的鸡类数据集要么只有几百张、要么只给分类标签不给检测框真正能拿来训练目标检测模型的少之又少。这个标题里的家禽鸡小鸡检测数据集2970 张图、VOC 和 YOLO 双格式、手工标注恰好卡在了「能直接开训」这个点上。它解决的核心问题是你不需要从零标 3000 张鸡图拿到就能跑通训练流程验证自己的检测方案在禽类场景下到底行不行。适合两类人——刚入门目标检测想找一个真实场景练手的以及做养殖智能化需要快速验证雏鸡检测可行性的工程师。手工标注意味着框的质量比自动标注靠谱VOC 和 YOLO 双格式意味着你不用写转换脚本就能对接不同框架。下面从数据本身讲到训练落地把这条链路走通。2. 拆开这个数据集VOC 与 YOLO 双格式的结构差异2.1 VOC 格式的目录结构与 XML 字段含义VOC 格式是目标检测领域最经典的标注格式之一它的组织方式是一图一 XML。拿到数据集后你通常会看到这样的目录结构dataset/ ├── JPEGImages/ # 所有原始图片jpg 格式 │ ├── 000001.jpg │ ├── 000002.jpg │ └── ... ├── Annotations/ # 每张图对应的 XML 标注文件 │ ├── 000001.xml │ ├── 000002.xml │ └── ... └── ImageSets/ └── Main/ ├── train.txt # 训练集图片名列表不含扩展名 ├── val.txt └── test.txt每个 XML 文件里最关键的是object节点它记录了标注框的类别和坐标。一个典型的 XML 长这样annotation folderJPEGImages/folder filename000001.jpg/filename size width640/width height480/height depth3/depth /size object namechicken/name !-- 类别名 -- poseUnspecified/pose truncated0/truncated !-- 是否被截断 -- difficult0/difficult !-- 是否难以识别 -- bndbox xmin112/xmin !-- 左上角 x -- ymin85/ymin !-- 左上角 y -- xmax340/xmax !-- 右下角 x -- ymax290/ymax !-- 右下角 y -- /bndbox /object /annotation这里有几个字段值得注意。name是类别标签这个数据集里大概率是 chicken、chick 或者统一成一个类。truncated和difficult在训练时可以选择性忽略——如果你想让模型专注学清晰目标可以把 difficult1 的框过滤掉。bndbox的坐标是绝对像素值原点在左上角这是 VOC 的标准约定。注意有些数据集的 XML 里会出现坐标越界的情况比如 xmax 大于图片宽度。训练前一定要做一遍校验否则 YOLO 转换时会直接报错或者生成错误的标签。2.2 YOLO 格式的归一化坐标与类别索引YOLO 格式和 VOC 最大的区别在于它把每张图的标注写成一个 txt 文件每行一个目标坐标是归一化后的中心点加宽高。对应的目录结构通常是dataset_yolo/ ├── images/ │ ├── train/ │ │ ├── 000001.jpg │ │ └── ... │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ │ ├── 000001.txt │ │ └── ... │ ├── val/ │ └── test/ └── data.yaml # 数据集配置文件每个 txt 文件的内容格式是class_id x_center y_center width height全部是 0 到 1 之间的浮点数。举个例子如果一张 640×480 的图里有一个框VOC 坐标是 (112, 85, 340, 290)转成 YOLO 格式就是0 0.353125 0.390625 0.356250 0.427083计算方式x_center (112340)/2/640 0.353125y_center (85290)/2/480 0.390625width (340-112)/640 0.356250height (290-85)/480 0.427083。data.yaml是 YOLO 训练时的入口配置文件内容一般长这样path: ./dataset_yolo train: images/train val: images/val test: images/test nc: 1 names: - chickennc是类别数names是类别名列表。这个数据集如果只有鸡一个类nc 就是 1。如果区分了大鸡和小鸡nc 就是 2names 里对应写 chicken 和 chick。2.3 两种格式的选型判断什么场景用哪个VOC 格式的优势在于通用性强。很多经典检测框架Faster R-CNN、SSD 的早期实现以及一些标注工具LabelImg默认就用 VOC。如果你要做格式转换、数据分析、可视化标注框XML 的可读性比 txt 好得多——至少你能直接打开看到坐标和类别名。YOLO 格式的优势在于训练效率。YOLO 系列v5、v8、v11 以及更新的版本原生吃这种格式不需要在训练时做在线转换。而且归一化坐标对图片缩放更友好数据增强时不用反复换算。我的建议是如果你确定用 YOLO 系列训练直接用 YOLO 格式那份省去转换步骤。如果你还在对比不同框架或者需要做数据清洗和可视化先用 VOC 格式做分析确认没问题后再转 YOLO。这个数据集同时给了两种格式省掉了很多来回折腾的时间。3. 从零跑通训练用 YOLOv8 在本地把鸡检测模型训起来3.1 环境配置与依赖安装的版本选择训练之前先把环境搭好。YOLOv8 对环境的容忍度比较高但有几个关键依赖的版本需要注意。我一般用 conda 建一个独立环境避免和系统里的其他包打架conda create -n chicken_det python3.10 -y conda activate chicken_det # 安装 PyTorch根据你的 CUDA 版本选对应命令 # CUDA 11.8 的情况 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 安装 ultralyticsYOLOv8 官方包 pip install ultralytics # 验证安装 yolo checkspython3.10是我实测下来兼容性最好的版本3.11 和 3.12 也能跑但偶尔会遇到某些依赖没有预编译 wheel 的情况。PyTorch 的版本跟着 CUDA 走如果你没有 GPU直接pip install torch torchvision装 CPU 版也能跑只是训练速度会慢很多。yolo checks会输出当前环境的信息包括 PyTorch 版本、CUDA 是否可用、GPU 型号等确认没有报错再往下走。提示如果你用的是 30 系或 40 系显卡建议 CUDA 11.8 以上。50 系显卡需要 CUDA 12.8 以上和 PyTorch 2.7 以上版本对不上会直接报 no kernel image 错误。3.2 数据集目录整理与 data.yaml 配置拿到数据集后先确认目录结构符合 YOLO 训练的要求。如果你的数据还是 VOC 格式需要先转成 YOLO 格式。转换脚本可以自己写也可以用现成的工具。下面是一个我常用的转换脚本处理了坐标越界和空标注的情况import os import xml.etree.ElementTree as ET from pathlib import Path def voc_to_yolo(xml_dir, img_dir, output_dir, class_names): xml_dir: VOC 标注文件夹路径 img_dir: 图片文件夹路径 output_dir: 输出 YOLO 标签的文件夹路径 class_names: 类别名列表如 [chicken] os.makedirs(output_dir, exist_okTrue) skipped 0 for xml_file in Path(xml_dir).glob(*.xml): tree ET.parse(xml_file) root tree.getroot() # 获取图片尺寸 size root.find(size) img_w int(size.find(width).text) img_h int(size.find(height).text) lines [] for obj in root.findall(object): cls_name obj.find(name).text.strip() if cls_name not in class_names: continue cls_id class_names.index(cls_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) # 坐标裁剪防止越界 xmin max(0, min(xmin, img_w)) ymin max(0, min(ymin, img_h)) xmax max(0, min(xmax, img_w)) ymax max(0, min(ymax, img_h)) # 跳过无效框 if xmax xmin or ymax ymin: skipped 1 continue # 转归一化中心点坐标 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}) # 写出对应的 txt 文件 txt_path Path(output_dir) / (xml_file.stem .txt) with open(txt_path, w) as f: f.write(\n.join(lines)) print(f转换完成跳过 {skipped} 个无效框) # 调用示例 voc_to_yolo( xml_dirdataset/Annotations, img_dirdataset/JPEGImages, output_dirdataset_yolo/labels/all, class_names[chicken] )这个脚本做了三件事读取 XML 里的图片尺寸和标注框、把绝对坐标转成归一化中心点坐标、写出 YOLO 格式的 txt。坐标裁剪那几行是血泪经验——有些标注员会不小心把框拉到图片外面不处理的话 YOLO 训练时会报 assert 错误。skipped计数器用来统计被跳过的无效框数量转换完看一眼如果跳过太多说明标注质量有问题。转换完成后按 train/val/test 划分数据集。我一般按 8:1:1 分如果数据量少可以 7:2:1。划分脚本很简单就是随机抽样加文件复制import random import shutil from pathlib import Path def split_dataset(img_dir, label_dir, output_dir, ratios(0.8, 0.1, 0.1)): img_dir Path(img_dir) label_dir Path(label_dir) output_dir Path(output_dir) # 获取所有图片文件名不含扩展名 stems [f.stem for f in img_dir.glob(*.jpg)] random.seed(42) # 固定随机种子保证可复现 random.shuffle(stems) n len(stems) n_train int(n * ratios[0]) n_val int(n * ratios[1]) splits { train: stems[:n_train], val: stems[n_train:n_train n_val], test: stems[n_train n_val:] } for split_name, split_stems in splits.items(): img_out output_dir / images / split_name lbl_out output_dir / labels / split_name img_out.mkdir(parentsTrue, exist_okTrue) lbl_out.mkdir(parentsTrue, exist_okTrue) for stem in split_stems: # 复制图片 src_img img_dir / f{stem}.jpg if src_img.exists(): shutil.copy(src_img, img_out / f{stem}.jpg) # 复制标签 src_lbl label_dir / f{stem}.txt if src_lbl.exists(): shutil.copy(src_lbl, lbl_out / f{stem}.txt) print(ftrain: {len(splits[train])}, val: {len(splits[val])}, test: {len(splits[test])}) split_dataset(dataset/JPEGImages, dataset_yolo/labels/all, dataset_yolo)random.seed(42)是为了保证每次划分结果一致方便复现实验。划分完之后检查一下每个子集的图片数和标签数是否一一对应缺标签的图片在训练时会被跳过但最好提前发现。3.3 启动训练与关键超参数设置数据准备好之后写一个data.yaml放在数据集根目录path: /absolute/path/to/dataset_yolo train: images/train val: images/val test: images/test nc: 1 names: - chickenpath建议写绝对路径相对路径在不同工作目录下容易出问题。然后就可以启动训练了yolo detect train \ datadataset_yolo/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/chicken \ nameexp1几个关键参数的含义和调整建议参数含义建议值调整逻辑model预训练权重yolov8n.pt / yolov8s.pt数据量 3000 张左右用 n 或 s 就够m 以上容易过拟合epochs训练轮数100~300看验证集 loss 曲线还在降就继续加imgsz输入尺寸640鸡的目标如果很小可以提到 1280但显存翻倍batch批大小16显存不够就降到 8 或 4配合 accumulate 使用lr0初始学习率0.01默认值通常够用loss 震荡厉害就降到 0.001patience早停耐心值2020 轮验证集指标不提升就停省时间yolov8n.pt是 YOLOv8 最小的预训练模型在 COCO 上预训练过。用预训练权重比从零训收敛快很多3000 张数据大概几十个 epoch 就能看到不错的 mAP。如果你的鸡目标特别小比如刚出壳的雏鸡在画面里只占几十个像素把imgsz提到 1280 会有明显提升但 batch 要相应降到 4 或 8。训练过程中重点看几个指标box_loss和cls_loss是否稳定下降、mAP50是否在涨、验证集 loss 和训练集 loss 的差距。如果训练集 loss 一直降但验证集 loss 开始涨就是过拟合了需要加数据增强或者减模型复杂度。3.4 训练结果解读与推理验证训练结束后runs/chicken/exp1/目录下会生成权重文件和评估结果。weights/best.pt是验证集上表现最好的权重weights/last.pt是最后一轮的。用 best.pt 做推理验证from ultralytics import YOLO model YOLO(runs/chicken/exp1/weights/best.pt) # 单张图片推理 results model(test_image.jpg, conf0.25, iou0.45) results[0].save(output.jpg) # 批量推理整个测试集 results model(dataset_yolo/images/test, conf0.25, saveTrue)conf0.25是置信度阈值低于这个值的检测框会被过滤掉。iou0.45是 NMS 的 IoU 阈值控制重叠框的合并程度。这两个参数对最终结果影响很大——conf 调高会减少误检但可能漏检调低则相反。建议在测试集上跑几组不同阈值画一条 P-R 曲线来选最优点。推理结果里每张图会输出检测框的坐标、类别和置信度。如果发现大量漏检先检查训练集的标注是否覆盖了各种场景光照、遮挡、密集程度再考虑调低 conf 或者增加训练轮数。如果误检多看看是不是背景里有和鸡颜色相近的物体可以加一些负样本图片进去。4. 避坑与排查训练鸡检测模型时最容易翻车的 5 个地方4.1 类别名不一致导致训练时全部标为背景现象训练日志里cls_loss一直是 0 或者异常低mAP 始终上不去推理时一个框都检测不出来。原因data.yaml里的names和标注文件里的类别索引对不上。比如标注里 chicken 的 class_id 是 0但 data.yaml 里 names 列表第一个是别的类别或者 nc 设成了 2 但实际只有 1 个类。解决转换完数据后用脚本统计一遍所有 txt 里出现的 class_id 集合确认和 data.yaml 的 nc 及 names 完全对应。这个检查花不了两分钟但能省掉几个小时的无效训练。4.2 图片和标签文件名不匹配导致大量样本被跳过现象训练时提示No labels found或者实际参与训练的图片数远少于预期。原因YOLO 要求图片和标签同名扩展名不同且放在对应的 images/labels 目录下。如果图片是000001.jpg但标签是000001_chicken.txt或者标签放在错误的子目录里就会被跳过。解决写一个校验脚本遍历 images 下所有图片检查 labels 下是否存在同名 txt。缺失的列出来要么补标签要么删图片。同时检查 labels 目录下有没有多余的 txt没有对应图片的这些也会被忽略。4.3 小目标检测效果差雏鸡在画面里太小现象大鸡能检测到小鸡漏检严重mAP50 里小目标的指标明显低于整体。原因YOLOv8 默认输入 640如果雏鸡在原图里只有 20×20 像素缩放到 640 后可能只剩几个像素特征提取网络根本抓不到。解决三个方向——把imgsz提到 1280 或更高用yolov8s或yolov8m这种更大的模型特征金字塔层数更多在数据增强里开启mosaic和scale让模型见过不同尺度的目标。如果显存不够用batch4配合accumulate4来等效大 batch。4.4 验证集指标虚高但实际推理效果差现象训练日志里 mAP50 到了 0.9 以上但拿真实场景的图片去测漏检误检一大堆。原因训练集和验证集来自同一批数据分布太接近。如果数据集里的图片都是同一养殖场、同一角度拍的模型只是记住了这个场景换一个环境就废了。解决划分验证集时确保覆盖不同场景——不同光照、不同背景、不同密度。如果数据集本身多样性不够做推理测试时一定要用训练集之外的图片。另外可以开启val时的save_jsonTrue把预测结果导出来逐张看比只看指标靠谱。4.5 显存溢出导致训练中断现象训练跑了几十个 epoch 突然报 CUDA out of memory或者一开始就起不来。原因batch或imgsz设太大或者同时开了太多数据增强 worker。另外如果训练过程中有内存泄漏某些版本的 ultralytics 有过这个问题跑久了也会 OOM。解决先把batch降到 4 试试能跑起来再逐步往上加。imgsz从 640 起步需要更高分辨率再往上调。设置workers4而不是默认的 8减少数据加载的显存占用。如果还是不行用yolo detect train ... device0明确指定单卡避免多卡通信的开销。5. 把 2970 张数据的价值榨干标注质量复核与增量标注技巧数据集到手直接用是最省事的但 2970 张里难免有标注瑕疵。我一般会花半天时间做一轮标注质量复核这一步的投入产出比极高。具体做法是用训练好的模型在训练集上跑一遍推理把预测框和原始标注框做 IoU 对比IoU 低于 0.5 的挑出来人工看。这些低 IoU 样本要么是标注框画歪了要么是模型确实没学好——两种情况都值得关注。from ultralytics import YOLO import cv2 model YOLO(runs/chicken/exp1/weights/best.pt) # 在训练集上推理找出预测和标注差异大的样本 results model(dataset_yolo/images/train, conf0.1, iou0.5, saveTrue, save_txtTrue) # 对比 save_txt 输出的预测标签和原始标签 # 逐张计算 IoU低于阈值的记录下来人工复核conf0.1故意设低是为了让模型多输出一些框方便和标注对比。save_txtTrue会把预测结果按 YOLO 格式存下来直接和原始标签做 diff 就行。复核的时候重点关注三类模型检测到但标注里没有的可能是漏标、标注里有但模型没检测到的可能是标错了或者目标太模糊、框位置明显偏移的。复核完之后如果发现某些场景下漏标严重可以针对性地补标。补标不需要从头来——用模型先预测一遍人工只修正错误的框效率比纯手工高好几倍。LabelImg 和 CVAT 都支持导入预标注结果在这个基础上改就行。补标的数据和原始数据混在一起重新训练通常能带来几个点的 mAP 提升。还有一个技巧是难例挖掘。训练完一轮后把验证集里 loss 最高的那批样本挑出来看看它们有什么共性——是遮挡严重、还是目标太小、还是背景干扰强。然后针对这些场景补充数据或者调整增强策略。这个循环做两三遍模型在真实场景下的鲁棒性会有明显改善。我自己踩过的最大坑是拿到数据集后急着跑训练忽略了标注复核结果模型在验证集上指标很好看部署到养殖场里发现一堆漏检。后来回头查标注发现有一批图片的框只标了鸡的身体没标头模型学到的特征不完整。花时间做标注复核这件事后悔药没得吃但提前做就是最好的保险。希望帮到你。本文还有配套的精品资源点击获取