☰
YOLOv8鸡行为数据集详解:从标签结构到训练部署全流程
2026/10/2 1:43:40 网站建设 项目流程

简介:一份面向智慧养殖与行为识别场景的家禽鸡行为数据集,支持识别吃食、喝水、死亡、睡觉及异常行为。484张训练集图片均采用YOLOv8格式标注,能够满足行为检测、状态监控与预警模型训练需求,适合计算机视觉初学者及养殖智能化项目开发者用于模型调优、效果验证与部署实践。资源共1429个文件,包含714个txt标注文件、714张jpg图像和1个yaml配置文件,压缩包大小约39.33MB。txt文件记录目标框坐标与类别,jpg图像对应真实养殖场景,yaml文件可直接用于配置模型训练参数,目录结构简洁清晰,图片与对应标注一一配套。目前已有419人学习下载。配套标注完整,可直接解压后按YOLOv8格式划分训练集使用,也便于根据实际场景扩充样本、调整类别或进行迁移学习,还可用于搭建养殖舍内自动化监测与动物健康评估流程,是一套紧密贴合畜牧场景的紧凑型行为识别数据基础。

1. 从鸡舍监控到行为识别:一组能直接开训的 YOLOv8 鸡行为数据集

做智慧养殖的朋友应该都有同感:鸡舍里最缺的不是摄像头,而是能读懂行为的数据。这组家禽鸡行为数据集一共 484 张训练图片,标注了吃食、喝水、死亡、异常行为、睡觉五类目标,全部是 YOLOv8 格式的 txt 标签。拿到手不需要再转换格式,配好环境就能直接训练一个鸡行为检测模型。它适合两类人:一是做养殖监控算法落地、需要真实场景数据做验证的工程师;二是刚接触 YOLOv8 自己数据集流程、想找一份标注规范的小样本目标检测的新手。我拆完这组数据后最大的感受是:类别定义很贴近实际鸡舍监控的诉求,但样本量偏少,需要配合数据增强和迁移学习才能训出可用的模型。后面我会把数据结构、训练参数、踩坑点一次说清楚,按这份清单走能省不少试错时间。

2. 数据集结构拆解:五类行为定义与标签文件的真实分布

2.1 类别定义与标注逻辑

这五类行为分别是吃食、喝水、死亡、异常行为、睡觉,对应英文标签可以命名为 eating、drinking、dead、abnormal、sleeping。先讲清楚每个类别的判定边界,因为训练时标签的语义一致性直接决定模型上限:

  • 吃食(eating):鸡的头部低垂至料槽内或正在啄食的动作,标注框应覆盖头部和颈部区域。
  • 喝水(drinking):鸡的喙部接触饮水器或头部做吞咽动作,注意与吃食区分的关键点是嘴部朝向。
  • 死亡(dead):鸡体躺卧不动、身体姿态异常扭曲,或者被其他鸡踩踏无反应。这个类别在监控场景里是最需要及时响应的。
  • 异常行为(abnormal):包括站立不动超过阈值、原地转圈、翅膀下垂、精神萎靡等非正常状态,是一个综合性类别。
  • 睡觉(sleeping):鸡只蹲伏、闭眼或头部藏于翅膀下,标注时通常框住整个身体轮廓。

这里有个容易被忽略的点:异常行为和死亡在某些姿态下从俯视视角看极其相似——一只死鸡如果侧躺且没有明显僵硬,模型很容易和睡觉、异常行为混淆。所以该数据集在异常行为上的标注框是否严格区分了“静止但存活”和“死亡”,直接关系到模型部署后的误报率。我建议拿到数据集后先逐类抽查 20~30 个标注框,看看边界语义是否一致,再决定是否需要手动修正部分标签。

2.2 目录结构与标签文件解析

YOLOv8 格式的标注本质上是归一化坐标的文本文件,每个图像对应一个同名 .txt。我拆解后典型的目录结构如下:

chicken_dataset/ ├── images/ │ ├── train/ │ │ ├── img001.jpg │ │ ├── img002.jpg │ │ └── ... │ └── val/ │ ├── img401.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── img001.txt │ │ ├── img002.txt │ │ └── ... │ └── val/ │ └── img401.txt └── data.yaml

每个 label 文件的内容长这样:

0 0.452148 0.381836 0.164062 0.252930 1 0.715820 0.625977 0.152344 0.229492 3 0.352539 0.744141 0.186523 0.302734

每一行的五个数字含义依次是:类别ID(从0开始)、目标中心点的 x 坐标(归一化)、目标中心点的 y 坐标(归一化)、目标宽度(归一化)、目标高度(归一化)。以第一行为例,类别 0 即吃食,中心位于图像宽度 45.2%、高度 38.2% 的位置,框宽约为图像宽度的 16.4%,框高约为图像高度的 25.3%。

计算真实像素坐标的办法是:像素 x = 归一化 x × 图像宽度,像素 y = 归一化 y × 图像高度。我在检查标注质量时会写个小脚本把所有框反算回图像上可视化,确认没有坐标越界或框体严重偏离目标。特别是死亡类别的框,如果标得比实际身体大很多,训练时会导致 IoU 计算不稳定,最终影响 mAP。

2.3 样本分布与训练验证划分策略

484 张训练图对五类行为来说并不算充裕。从分布经验上看,吃食和喝水通常是高频行为,睡觉次之,死亡和异常行为属于低频但关键事件。这就导致一个典型的类别不平衡问题:模型容易把稀缺类别(死亡、异常行为)漏检,因为训练时见过的正样本太少。

我在处理这类小样本数据集时通常的做法是:

  • 先用os.listdir统计 labels 目录下每个类别出现的次数,画出分布直方图。
  • 如果死亡、异常行为的框数量少于总数量的 5%,就要优先考虑数据增强策略,而不是盲目加训练轮数。
  • 验证集不要只按文件名顺序抽末尾,应保证每个类别至少有几张包含样本,否则验证集里如果没有死亡目标,训练过程会一直显示该类别的 precision 为 0,容易误判模型没收敛。

一个简单的类别统计脚本:

import os from collections import Counter label_dir = "chicken_dataset/labels/train" counter = Counter() for fname in os.listdir(label_dir): if not fname.endswith(".txt"): continue with open(os.path.join(label_dir, fname), "r") as f: for line in f: cls_id = int(line.strip().split()[0]) counter[cls_id] += 1 for cls_id, cnt in counter.items(): print(f"类别 {cls_id}: {cnt} 个目标框")

这段脚本的核心逻辑是遍历训练标签目录,对每个 txt 文件逐行读取首列类别ID并计数。如果你看到类别 3(死亡)和类别 4(异常行为)的数量明显低于前几个类别,后面训练时就要考虑给它们单独加权,或者在损失函数里提高这两类的权重。YOLOv8 的 class weights 参数可以传入一个列表,按类别分配不同的 loss 权重。

3. 基于 YOLOv8 的训练配置与完整复现流程

3.1 环境准备与数据集路径组织

YOLOv8 官方实现是 ultralytics 库,安装时一定要锁定版本。我实测下来 ultralytics 8.x 的不同小版本在数据增强策略上有调整,如果你照着网上的旧教程配了参数,训练出来的指标可能对不上。建议用pip install "ultralytics>=8.2.0"装一个新一点的版本,同时可以用nvidia-smi确认显卡驱动和 CUDA 版本,再用python -c "import torch; print(torch.cuda.is_available())"验证 PyTorch 的 GPU 可用性。

数据集路径注意事项:YOLOv8 的 data.yaml 里 path 字段如果是相对路径,会相对于当前工作目录解析,很容易出现路径对不上导致训练直接报错找不到图片。我一般会把数据集放在训练脚本同级的固定目录下,并改写为绝对路径,或者直接用path: ./chicken_dataset并保证在项目根目录执行训练命令。

# data.yaml path: ./chicken_dataset train: images/train val: images/val nc: 5 names: 0: eating 1: drinking 2: dead 3: abnormal 4: sleeping

这里的 nc 表示类别总数,names 里必须和标签文件的类别ID一一对应。如果标签文件里出现了 ID 5 而 names 只定义了 5 个名字,yolov8 训练时会直接抛出类别索引越界的错误。还有一点值得注意:train 和 val 字段不要带绝对路径前缀,只要相对于 path 的相对路径即可,ultralytics 会自动拼接。

3.2 训练脚本与关键参数的选择逻辑

基础训练代码非常短:

from ultralytics import YOLO model = YOLO("yolov8n.pt") model.train( data="chicken_dataset/data.yaml", epochs=100, imgsz=640, batch=8, patience=15, device=0, workers=4, lr0=0.01, augment=True, )

代码逻辑说明:加载预训练的 YOLOv8n 权重作为起点,这是迁移学习的标准做法。n 是 nano 系列,参数量最小,适合只有 484 张图的小数据场景。如果你直接拿 YOLOv8x 超大模型来训,因为参数空间太大而训练样本少,极其容易过拟合——训练集 loss 降到 0.02,验证集 mAP 却始终在 0.3 徘徊。

参数细节解释:

  • imgsz 设为 640 是速度和精度之间的折中。鸡舍监控通常是大画面里的小目标,如果你发现鸡在画面中占比很小,可以改成 960 甚至 1280,但显存会呈平方级上升。
  • batch 大小取决于显存。8GB 显存跑 yolov8n 用 batch 8 比较稳,如果显存不足可以降到 4,同时调低 workers。
  • patience 是早停参数,验证集 mAP 连续 15 轮没有上升就停止训练,避免无谓的算力消耗。
  • lr0 是初始学习率,小数据集建议保持 0.01 而不是调大,0.1 的初始学习率在这种数据规模下很容易发散。
  • augment 开启后默认使用 mosaic、随机仿射、翻转等策略,对小样本很有帮助。

3.3 数据增强参数与超参调优的空间

YOLOv8 对增强策略暴露了很多可调参数,对这份小数据集来说,我最常用改动的是这几个:

model.train( data="chicken_dataset/data.yaml", epochs=150, imgsz=640, batch=8, hsv_h=0.02, # 色调增强范围 hsv_s=0.6, # 饱和度增强幅度 hsv_v=0.4, # 明度增强幅度 degrees=5, # 旋转角度,鸡舍摄像头基本水平,不要给太大 translate=0.1, # 平移增强 scale=0.4, # 缩放增强 fliplr=0.5, # 水平翻转 mosaic=0.8, # mosaic 增强概率 )

鸡舍场景和自然场景不同,摄像头固定、光照变化规律,所以旋转增强应该小一些,否则模型学了颠倒的鸡反而徒增学习负担。色调略微调一点就行,因为养殖场灯光通常是暖色恒定的。如果你发现验证集 mAP 不错但实际部署时误检多,可以尝试把 mosaic 降到 0.5 来减少小目标拼接导致的误标,同时增加 scale 让模型对不同距离的目标更鲁棒。

这里还涉及一个很玄学的点:同样的参数,迁移学习加载的不同预训练权重,最终收敛效果差异很大。我习惯分别跑 yolov8n.pt 和 yolov8s.pt 两个基础模型对比一次,选验证集 mAP 更高的那个继续迭代,而不是一上来就死磕某个模型规模。

3.4 训练过程监控与模型评估

训练开始后,终端会逐轮打印 loss、precision、recall、mAP50、mAP50-95 这些指标。对这份鸡行为数据集的具体判读建议:

  • mAP50 达到 0.7 以上,说明模型基本能正确框出大部分目标,可以作为初步可用模型。
  • mAP50-95 相对偏低是正常现象,因为框的精细度要求更高,小目标会拖累这个指标。
  • recall 低于 precision 时,说明漏检比误检更严重,需要关注稀有类别。
  • 训练结束后会用model.val()自动跑验证,并输出每个类别的详细指标。重点看 dead 类别的 AP,那是监控场景的核心价值所在。
from ultralytics import YOLO best_model = YOLO("runs/detect/train/weights/best.pt") metrics = best_model.val(data="chicken_dataset/data.yaml") print(metrics.box.map) # mAP50-95 print(metrics.box.map50) # mAP50 print(metrics.box.maps) # 每个类别的 AP

这段代码的作用是加载训练期间保存的最佳权重文件,在验证集上重新计算各项评估指标。metrics.box.maps 返回的是长度为 5 的数组,分别对应五个类别的平均精度。如果某个类别的值明显低于整体水平,说明该类目标在验证集中占比太少或标注不一致,需要针对性补数据。

4. 避坑与常见问题排查:从标签错位到训练不收敛的五条血泪经验

4.1 YOLOv8 训练直接报错:标签类别 ID 与 names 配置不一致

现象:训练刚启动,会在 verify 阶段报出类似IndexError: list index out of range的错误,有时还伴随大量警告提示 label 文件读取异常。

原因:label 文件中出现了 data.yaml 的 names 列表长度之外的类别编号。比如数据集里某个 txt 首列是 5,而 names 只定义了 0~4 五个类别。

解决:写一个小脚本扫描全部标签文件的最大类别 ID,和 names 数量比对,不一致就重新映射编号。现象排查脚本如下:

import os label_dirs = [ "chicken_dataset/labels/train", "chicken_dataset/labels/val" ] max_cls = -1 for label_dir in label_dirs: for fname in os.listdir(label_dir): if not fname.endswith(".txt"): continue with open(os.path.join(label_dir, fname)) as f: for line in f: cls_id = int(line.split()[0]) max_cls = max(max_cls, cls_id) print(f"标签文件中的最大类别 ID: {max_cls}") print(f"data.yaml 中 nc 应为: {max_cls + 1}")

核心逻辑就是遍历所有 label 文件,提取每个框的类别 ID 并取最大值,输出结果和配置文件比对。如果你的数据集类别编号是从 1 开始而不是 0,也会出现这种错位,需要整体减一。

4.2 模型训练 loss 快速下降但验证 mAP 一直很低

现象:训练前 20 轮训练集 loss 就降到 0.03 左右,但验证集 mAP50 始终在 0.2~0.4 之间徘徊,几乎不上涨。

原因:典型的过拟合或数据分布偏差。484 张训练图太少,模型把训练集的颜色、纹理、背景记住了,没有学到泛化的鸡形态特征。另一个可能是训练集和验证集来自不同的光照条件或拍摄角度,比如训练集在白天,验证集包含大量夜间红外图像。

解决:先查看训练集和验证集图片的来源,确认拍摄条件是否一致。如果不一致,把验证集里特殊场景的图片挪一部分到训练集。然后调节增强参数,把 mosaic 概率调低、scale 调大,降低模型对具体纹理的依赖。最后可以把批次 epoch 降到 80 以下,早停 patience 调到 10,防止在过拟合区间反复横跳。

4.3 死亡鸡只漏检率极高,模型几乎识别不出 dead 类

现象:吃食和喝水检测效果尚可,但死亡类别的 recall 低于 0.2,甚至验证集里一张死鸡都检不出来。

原因:这是小样本加类别不平衡的叠加结果。死亡是低频事件,原始训练集里可能只有几十个 dead 框,模型在训练过程中对该类别的梯度贡献太小,被其他高频类别淹没。

解决:优先做针对性的复制粘贴增强——把包含 dead 目标的图像单独抽出,做平移、旋转、亮度调整后复制多份加入训练集。同时,在训练时传入类别权重:

model.train( data="chicken_dataset/data.yaml", epochs=150, imgsz=640, batch=8, class_weights=[1.0, 1.0, 3.0, 3.0, 1.0] )

class_weights 列表的顺序必须和 names 一致。给 dead 和 abnormal 各分配 3.0 的权重,相当于在损失计算时放大这两类误检的代价,让优化器更加重视它们。如果训完效果仍然不理想,就需要人工补充标注几十张死鸡图片再做一轮微调,单纯调参无法从根本上解决样本存在性问题。

4.4 摄像头远距离场景下小目标完全检测不到

现象:训练和验证时 mAP 指标尚可,但部署到 8 米高的鸡舍角落摄像头画面中,鸡只有几十个像素,模型基本漏检。

原因:训练图像的标注目标框占比普遍在 10%~30%,而实际部署场景中的鸡目标框占比可能只有 2%~5%。模型没见过这种尺度的目标,自然检测不到。

解决:把训练输入尺寸从 640 提升到 960,虽然显存占用增大,但相对目标会更清晰。更彻底的办法是让模型学习对多尺度更鲁棒——把 scale 增强从 0.4 提高到 0.8,让模型在训练时不断看到大小不同的鸡。如果部署场景固定,还可以把部署画面切分为四个区域分别跑检测,牺牲部分速度换取小目标召回率的提升。

4.5 验证集指标正常但实际推断时误检大量饮水器

现象:实际测试时,饮水器、料槽边缘被反复框出来,且是高置信度。

原因:数据集的负样本不足。模型中吃到足够多“像鸡但不是鸡”的背景信息,导致它把颜色接近、纹理块状的水滴或柱状物误判为鸡。另一个常见原因是标签漏标——明明图里有鸡却没框,训练时该区域被当成背景,模型学到前后矛盾的特征。

解决:收集 100~200 张不含鸡的纯鸡舍背景图,放入训练集并生成空的 txt 标签,这些负样本会显著压低误检。然后用训练好的模型对这些背景图做 batch 推断,把所有置信度超过 0.25 的检测结果可视化出来逐一检查,确认误检来源再补充难例。负样本的加入对监控类项目的帮助,往往比你想象得还要大。

5. 从检测结果到养殖告警逻辑:行为统计与事件判定技巧

模型训练完只是第一步,真正让这份数据集发挥价值的是把检测框变成可用的行为统计和告警事件。我在部署鸡行为检测时,常用逻辑是先做追踪再统计每只鸡在各行为上的停留时长和切换频次,而不是简单地单帧判断。

from collections import defaultdict import numpy as np # 统计一段视频中每帧各类别出现次数 stats = defaultdict(lambda: {"frames": 0, "conf_list": []}) for result in results: boxes = result.boxes for box in boxes: cls_id = int(box.cls[0]) conf = float(box.conf[0]) stats[cls_id]["frames"] += 1 stats[cls_id]["conf_list"].append(conf) # 输出平均置信度与出现帧数占比 total_frames = len(results) for cls_id, s in stats.items(): avg_conf = np.mean(s["conf_list"]) ratio = s["frames"] / total_frames * 100 print(f"类别 {cls_id}: 平均置信度 {avg_conf:.3f},出现帧数占比 {ratio:.1f}%")

这段代码的逻辑是对视频检测结果做帧级统计,计算每个行为出现的频率和平均置信度。如果某类行为在正常时间段出现比例异常升高,比如从 5% 突增到 80%,系统就可以触发告警。

死亡和异常行为的告警需要更重的判定条件。单帧出现 dead 框可能是鸡卧倒休息,但连续 30 帧以上同一位置持续存在 dead 框且置信度高,就值得推送给饲养员。我通常结合 ByteTrack 或 BoT-SORT 对目标做 ID 追踪,如果一个 ID 在超过 N 帧的跟踪中被标记为 dead,才发出通知。这样能有效降低因鸡被遮挡或姿态短暂变化导致的误报。

对于吃食和喝水的节律分析,可以把一天内每小时的检测次数导出成折线图,正常的鸡群会呈现早晚两个进食高峰。如果喝水次数在某个时段骤降,往往先于疾病症状出现,提前预警的意义比死亡检测更大。这组数据集的场景价值,恰恰在于用 484 张图启动一个完整的监测闭环——从检测到统计再到告警规则,先跑通再逐步补充数据迭代。

我自己的习惯是拿到任何新数据集,第一周只做一件事:可视化所有标注框,找出语义不一致的标签并修正。从那以后我每次训练前都强制走一遍这个流程,看起来多花了两三个小时,但换来的往往是训练轮数减少一半、mAP 提升 0.2。希望这套流程和踩坑清单也能帮你在鸡行为检测项目上少走弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询