
简介这份鸡状态数据集面向家禽养殖监控、智慧农业算法研发及计算机视觉学习者用于识别正常与异常状态的鸡只可支撑异常行为预警、健康巡检等场景适合具备一定目标检测基础的中高级开发者。资源包共2000个文件以1997张jpg图像为主体另附3个json标注文件压缩包约451.26MB图像与标注配套齐全可直接投入训练流程。数据集包含3749张训练集图片平均正常识别率约91.8%标注采用coco json格式便于对接主流检测框架减少格式转换成本。目前已有410人学习下载具备一定参考热度。读者可据此搭建家禽状态监测模型借助完整标注与图像样本开展训练、验证与调优快速复现异常识别效果并在此基础上迁移到其他家禽或畜牧场景节省数据采集与标注时间。1. 鸡状态数据集3749 张图、91.8% 正常识别率这套监控方案到底怎么落地养殖场里最怕的不是鸡生病而是病了好几天没人发现。一个千羽规模的鸡舍饲养员每天巡棚两三次靠肉眼判断哪只鸡精神萎靡、羽毛蓬乱、缩脖呆立漏检率其实很高。鸡状态数据集就是冲着这个场景来的3749 张训练集图片标注了正常鸡和异常鸡两类目标支持 COCO JSON 格式官方给出的平均正常识别率在 91.8% 左右。说白了它想解决的是「用摄像头自动盯鸡群把异常个体框出来」这件事。这套数据适合谁做智慧养殖视觉方案的工程师、想拿家禽行为做目标检测练手的学生、以及需要给现有监控系统加一路异常告警的集成商。它不是一个开箱即用的产品而是一份需要你自己搭训练管线、调阈值、接业务逻辑的原料。下面我按「数据长什么样 → 怎么训 → 怎么调 → 坑在哪 → 怎么上线」的顺序把这条链路拆开讲。2. 先看清数据COCO JSON 里到底存了什么拿到一份标注数据集第一件事不是急着写训练脚本而是把标注结构摸清楚。COCO JSON 的字段设计决定了你后面怎么解析、怎么转格式、怎么做数据增强。很多人跳过这一步直接跑 YOLO 训练结果类别对不上、框偏移、图片路径找不到白白浪费一晚上 GPU 时间。2.1 COCO JSON 的四个核心字段与鸡状态数据的对应关系COCO 格式的标注文件本质是一个大字典关键字段有四个images、annotations、categories、info。对应到鸡状态数据集结构大致是这样字段含义鸡状态数据里的实际内容images图片元信息列表每张图的 id、文件名、宽高annotations标注框列表每个框的 id、image_id、category_id、bbox、area、iscrowdcategories类别定义id1 正常鸡id2 异常鸡具体 id 以实际文件为准info数据集描述版本、描述等元数据bbox的格式是[x, y, width, height]注意是左上角坐标加宽高不是[x1, y1, x2, y2]。这个细节在转 YOLO 格式时如果搞错框会整体偏移甚至跑到图外。iscrowd字段在鸡群密集场景下要特别留意如果标注时把重叠严重的鸡标成了 crowd训练时这类框的损失计算方式会不同。先用一段脚本把数据集的统计信息打出来确认类别分布和框的尺寸分布import json from collections import Counter with open(annotations/instances_train.json, r) as f: data json.load(f) # 类别分布 cat_map {c[id]: c[name] for c in data[categories]} cat_counter Counter(ann[category_id] for ann in data[annotations]) for cid, cnt in cat_counter.items(): print(f类别 {cat_map[cid]}: {cnt} 个框) # 每张图的平均框数 img_ids set(ann[image_id] for ann in data[annotations]) print(f有标注的图片数: {len(img_ids)}) print(f平均每张图框数: {len(data[annotations]) / len(img_ids):.2f}) # 框的宽高分布 widths [ann[bbox][2] for ann in data[annotations]] heights [ann[bbox][3] for ann in data[annotations]] print(f框宽 min/mean/max: {min(widths):.1f}/{sum(widths)/len(widths):.1f}/{max(widths):.1f}) print(f框高 min/mean/max: {min(heights):.1f}/{sum(heights)/len(heights):.1f}/{max(heights):.1f})这段脚本的作用是让你对数据规模有个量化认知。如果异常鸡的框数远少于正常鸡比如 1:5 甚至更悬殊那训练时就要考虑类别加权或者过采样。框的宽高分布则决定了 anchor 尺寸怎么设——如果大部分框都在 80×80 像素以下用默认的 COCO anchor 会很不匹配。2.2 从 COCO 转 YOLO 格式转换脚本与三个边界坑COCO 转 YOLO 是这条链路里最容易翻车的一步。YOLO 的标注格式是每行class_id x_center y_center width height全部归一化到 0~1。转换时有三类坑坐标归一化用错宽高、类别 id 从 0 还是 1 开始、图片路径和标注文件对不上。import json import os from PIL import Image def coco_to_yolo(coco_json, img_dir, out_dir): with open(coco_json) as f: data json.load(f) # 建立 image_id - 图片信息 的映射 img_info {img[id]: img for img in data[images]} # 类别 id 重映射COCO 的 id 可能不连续YOLO 要求从 0 开始 cat_ids sorted(set(c[id] for c in data[categories])) cat_remap {old: new for new, old in enumerate(cat_ids)} os.makedirs(out_dir, exist_okTrue) # 按 image_id 聚合标注 from collections import defaultdict ann_by_img defaultdict(list) for ann in data[annotations]: ann_by_img[ann[image_id]].append(ann) for img_id, anns in ann_by_img.items(): info img_info[img_id] w, h info[width], info[height] lines [] for ann in anns: x, y, bw, bh ann[bbox] # 归一化中心点坐标和宽高都除以图片尺寸 xc (x bw / 2) / w yc (y bh / 2) / h nw bw / w nh bh / h # 裁剪到 [0,1]防止标注越界导致训练报错 xc, yc min(max(xc, 0), 1), min(max(yc, 0), 1) nw, nh min(max(nw, 0), 1), min(max(nh, 0), 1) cls cat_remap[ann[category_id]] lines.append(f{cls} {xc:.6f} {yc:.6f} {nw:.6f} {nh:.6f}) # 写标注文件文件名与图片同名但后缀为 .txt base os.path.splitext(info[file_name])[0] with open(os.path.join(out_dir, base .txt), w) as f: f.write(\n.join(lines)) coco_to_yolo(annotations/instances_train.json, images/train, labels/train)逻辑说明先建立 image_id 到图片元信息的映射再按 image_id 聚合标注。归一化时中心点坐标是(x w/2) / img_w不是x / img_w这是最常见的错误。类别重映射是因为 COCO 的 category_id 可能从 1 开始或者不连续而 YOLO 要求从 0 开始连续编号。裁剪到 [0,1] 是防御性编程实际数据里如果有标注越界不裁剪会导致训练时 loss 变 NaN。参数说明coco_json是标注文件路径img_dir是图片目录转换本身不需要读图片但保持参数一致性方便后续校验out_dir是 YOLO 标注输出目录。转换完成后务必抽查几张图的标注是否对齐可以用 PIL 画框可视化验证。3. 训练管线从 3749 张图到 91.8% 识别率的关键参数数据摸清楚了接下来是训练。3749 张图在目标检测任务里属于中小规模不算多但也不至于要预训练从头来。关键是把增强策略、学习率调度、anchor 尺寸这三件事调对。91.8% 这个数字是在特定测试集和特定阈值下得到的你自己训出来的结果会有波动别把它当成硬指标。3.1 选 YOLOv8 还是 YOLOv5小数据集上的实测差异在鸡状态这种两类目标、中小规模数据集上YOLOv8n 和 YOLOv5s 是常见起点。我的经验是YOLOv8 的默认增强策略更激进在小数据集上容易过拟合到增强后的分布YOLOv5 的配置更透明调参空间大。如果追求快速出 baselineYOLOv8n 开箱即用如果要精细控制增强强度和 anchorYOLOv5s 更顺手。不管选哪个输入分辨率建议从 640 起步。鸡舍监控画面里单只鸡在整幅图中的占比通常不大640 分辨率下小目标可能只有 30~50 像素再低就丢细节了。如果显存允许可以试 960 或 1280但要注意小数据集上高分辨率更容易过拟合。# dataset.yaml path: ./chicken_dataset train: images/train val: images/val nc: 2 names: 0: normal 1: abnormal这个配置文件是 YOLO 系列的标准数据描述文件。nc是类别数names是类别名到 id 的映射必须和转换后的标注文件里的 class_id 一致。path是数据集根目录train和val是相对路径。如果验证集是从训练集里切出来的建议按 8:2 分层抽样保证异常样本在验证集里也有足够数量。3.2 异常样本少怎么办类别加权与过采样的取舍鸡群监控场景里异常鸡的数量天然少于正常鸡。如果异常样本只占 10%~20%直接训练会导致模型偏向预测正常类异常召回率上不去。两种处理方式一是在 loss 里给异常类更高权重二是对含异常样本的图片过采样。# 在 YOLO 训练脚本里自定义类别权重以 YOLOv5 为例 # 修改 loss.py 中的 BCEWithLogitsLoss 部分 class_weights torch.tensor([1.0, 3.0]) # 正常:异常 1:3 criterion nn.BCEWithLogitsLoss(pos_weightclass_weights)类别加权的逻辑是让异常类的分类损失放大模型更关注异常样本。权重设多少要看实际比例一般设成正常:异常 1:2 到 1:5 之间。过采样则是复制含异常的图片简单粗暴但容易过拟合。我一般先用类别加权如果异常召回率还是低于 80%再考虑过采样且过采样倍数不超过 2 倍。3.3 训练命令与关键超参epochs、batch size、学习率怎么定以 YOLOv8 为例一条完整的训练命令yolo detect train \ datadataset.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ warmup_epochs3 \ patience30 \ augmentTrue \ mosaic1.0 \ mixup0.1 \ degrees10 \ translate0.1 \ scale0.5 \ fliplr0.5 \ projectruns/chicken \ nameexp01参数说明epochs150是上限配合patience30做早停验证集 loss 30 轮不降就停。lr00.01是初始学习率lrf0.01是最终学习率因子余弦退火到初始的 1%。warmup_epochs3让学习率从低到高预热避免一开始就大步长震荡。mosaic1.0是马赛克增强把四张图拼成一张对小数据集很有效但如果鸡的尺度差异大mosaic 可能让模型学到不真实的上下文可以降到 0.5。mixup0.1是图像混合增强轻度使用即可。degrees10是旋转角度鸡的姿态变化不大不需要太大。fliplr0.5是水平翻转概率鸡的左右对称性不强翻转是安全的。训练过程中重点看三个指标metrics/mAP50、metrics/mAP50-95、以及异常类的召回率。如果 mAP50 到 0.9 以上但异常召回率只有 0.7说明模型把异常当正常了要回去调类别权重。如果训练 loss 持续下降但验证 loss 上升就是过拟合减少 epochs 或降低增强强度。4. 避坑与排查91.8% 背后容易忽略的五个问题91.8% 这个数字听起来不错但落到实际场景里光照变化、遮挡、摄像头角度偏移都会让性能打折扣。下面五条是我在类似项目里踩过的坑按「现象 → 原因 → 解决」写清楚。4.1 验证集 mAP 很高上线后漏检严重现象本地验证集 mAP50 到 0.92部署到鸡舍摄像头后异常鸡漏检率超过 30%。原因验证集和训练集来自同一批图片光照、角度、鸡的品种都一致。实际摄像头画面有逆光、夜间红外、镜头畸变分布差异大。解决从实际摄像头采集一批未标注图片人工标 200~300 张做测试集用这个测试集评估。如果差距大把实际画面加入训练集做微调或者做光照增强随机调整亮度、对比度、加噪声。4.2 异常类召回率始终上不去现象正常类 AP 到 0.95异常类 AP 只有 0.75调学习率没用。原因异常样本太少或者异常的定义太模糊。比如「精神萎靡」和「正常站立」在静态图里差别很小标注一致性差。解决先检查标注一致性同一张图让两个人标看 IoU 差异。如果标注本身模糊考虑把异常拆成更具体的子类如「缩脖」「羽毛蓬乱」「闭眼」或者引入时序信息用连续几帧判断。单纯靠静态图有些异常确实分不出来。4.3 框重叠时 NMS 把异常鸡框掉了现象鸡群密集时异常鸡和旁边的正常鸡框高度重叠NMS 后异常框消失。原因NMS 的 IoU 阈值默认 0.45~0.5密集场景下正常鸡和异常鸡的框 IoU 可能超过这个值异常框被抑制。解决调高 NMS 的 IoU 阈值到 0.6~0.7或者用 Soft-NMS。如果异常鸡总是被正常鸡框住检查标注时是否把异常鸡单独框出来了而不是被正常鸡的框覆盖。4.4 训练 loss 震荡不收敛现象loss 在 0.5~2.0 之间反复跳mAP 不涨。原因学习率太大、batch size 太小、或者标注里有越界框导致梯度爆炸。解决先把学习率降到 0.001 试如果还震荡检查标注文件里有没有坐标超过 1.0 的框。用前面转换脚本里的裁剪逻辑可以预防这个问题。另外 batch size 小于 8 时BN 层统计量不稳定建议用梯度累积或者换 GroupNorm。4.5 推理速度达不到实时现象模型在服务器上跑 30 FPS部署到边缘设备只有 5 FPS。原因边缘设备算力有限YOLOv8n 在 ARM 上没做量化优化。解决用 ONNX Runtime 或 TensorRT 做推理加速INT8 量化后速度能提升 2~3 倍精度损失通常在 1~2 个点。如果还不行降输入分辨率到 416 或 320但要注意小目标召回率会下降。5. 从检测框到告警把 91.8% 变成可用的监控逻辑模型训出来只是第一步真正上线要解决的是「怎么把检测结果变成饲养员能用的告警」。这里分享一个我常用的后处理策略滑动窗口计数加阈值触发。5.1 用滑动窗口平滑检测结果减少误报单帧检测会有抖动某帧把正常鸡误判成异常如果直接告警就是误报。做法是维护一个长度为 N 的队列记录最近 N 帧的异常鸡数量当异常比例超过阈值且持续 M 帧才触发告警。from collections import deque class AlertSmoother: def __init__(self, window30, threshold0.05, persist10): self.window deque(maxlenwindow) # 最近 30 帧的异常比例 self.threshold threshold # 异常比例阈值 5% self.persist persist # 持续 10 帧才告警 self.counter 0 def update(self, total, abnormal): ratio abnormal / max(total, 1) self.window.append(ratio) avg_ratio sum(self.window) / len(self.window) if avg_ratio self.threshold: self.counter 1 else: self.counter 0 return self.counter self.persist # 使用示例 smoother AlertSmoother(window30, threshold0.05, persist10) # 每帧调用 # if smoother.update(total_chickens, abnormal_chickens): # trigger_alert()逻辑说明window30是滑动窗口长度按 10 FPS 算就是 3 秒。threshold0.05是异常比例阈值超过 5% 的鸡异常才值得关注。persist10是持续帧数避免瞬时波动触发告警。这三个参数要根据实际场景调鸡舍越大window 可以越长异常定义越严格threshold 可以越低。5.2 告警分级与人工复核队列不是所有异常都要立刻叫人。我一般分三级绿色异常比例 3%记录不告警、黄色3%~8%推送消息给饲养员、红色 8% 或持续 5 分钟以上电话告警。同时把触发告警的帧截图存下来进人工复核队列饲养员确认后标记为真阳性或假阳性这些反馈数据可以拿回来做模型迭代。5.3 模型迭代用线上反馈数据做增量训练上线后每周收集一批人工复核过的图片把假阳性和假阴性样本加入训练集用低学习率做增量训练。注意不要全量重训容易把之前学好的特征覆盖掉。增量训练时学习率设成初始的 1/10epochs 控制在 20~30只微调最后几层。我自己的习惯是每次增量训练前先把新数据和旧数据混在一起打乱避免模型只记住新样本。另外如果连续两周假阳性率没有下降说明当前模型架构或数据标注有问题该停下来重新审视标注规范而不是继续堆数据。这套流程跑顺了91.8% 只是一个起点实际场景里的可用性会随着反馈闭环逐步提升。希望帮到你。本文还有配套的精品资源点击获取