1272张图达到92.6%识别率:猪行为识别YOLOv8实战解析
发布时间:2026/9/28 1:24:26来源:尧图网络
简介一套面向猪圈场景的猪只行为识别数据集可识别饮水、采食、睡觉、站立等典型行为平均正确识别率达到92.6%服务于动物行为分析、健康监测与养殖智能化研究适合计算机视觉、目标检测方向的研究者、算法工程师及农业信息化相关专业学生使用。数据规模为1272张标注图片资源包共包含2000个文件其中727张jpg图像为从多段真实猪舍视频中抽帧得到的画面1272个txt文件为YOLOv8格式标注1个yaml文件预设了类别名称与训练路径整体约85.86MB解压后即可用于模型训练与验证。图像素材覆盖不同猪圈机位、光照和猪只姿态标注内容包括喝、吃、睡觉、站立四个类别能够直接支撑YOLOv8等目标检测算法的训练、测试和迁移学习有效降低数据采集与标注成本。目前已有224人学习下载适合作为猪只行为识别、养殖场景视频分析等课题的基准数据集也可用于算法效果对比与模型调优。1. 猪行为识别数据集1272张图怎么支撑起92.6%的识别率养猪场里最费人力的一件事就是盯着监控判断猪的状态有没有在喝水、吃料是睡了还是站着发呆。猪行为识别数据集要解决的正是这个巡检场景。它包含1272张猪圈实拍图片标注了喝、吃、睡觉、站立4类行为按YOLOv8的txt格式组织作者给出的平均识别率是92.6%。对刚接触目标检测的从业者来说这是一个可以直接拿去训练和验证的数据集对已经在做养殖视觉方案的人它的价值更多在于提供了一个小而完整的基线——图片不多标注规范能快速判断一套训练流程通不通。不过1272张对4类行为来说属于典型的小数据集92.6%这个指标也得分清楚是mAP还是分类准确率。把它当作一个值得动手的项目来做而不是当作一个开箱即用的现成模型才是这个数据集真正的打开方式。下面我按数据拆解、训练复现、避坑、调优、部署的顺序把整条链路讲透。2. 拆解猪行为数据集YOLOv8标注格式、类别边界与92.6%的来历2.1 YOLOv8格式标注长什么样YOLOv8沿用的是YOLO系的目标检测标注规范一张图片对应一个同名.txt文件每一行代表一个目标框格式是class_id x_center y_center width height坐标都做了归一化处理数值范围在01之间。我在验证数据集时一般会先随机抽一张图和它的txt对照着看确保坐标和画面内容能对上。# 查看一张图片对应的标注文件 cat images/train/0001.txt2 0.458333 0.362500 0.166667 0.183333 0 0.610000 0.540000 0.120000 0.150000第一行的第一个数字2代表类别ID后面4个数分别是目标中心x、中心y、框宽、框高全部归一化。解析的时候要注意坐标是归一化的画框必须乘回原图宽高。如果原数据集是用Labelme这类工具标注后导出的特别容易在类别ID映射上翻车——Labelme的类别列表按导入顺序排列和YOLO的class_id不一定一致拿到手先用脚本统计txt里的id集合再和data.yaml里的names顺序核对一遍。2.2 四类行为的视觉边界喝、吃、睡觉、站立怎么区分这个数据集的类别定义不是严格意义上的动作瞬间而是行为状态。喝水通常指猪把嘴伸到饮水器附近并有吞咽动作站立是四肢着地、没有进食饮水。难点在于猪喝水的瞬间和站立吃料时的姿态非常接近标注员如果只看单张静态图很容易把正在喝水标成站立。处理这种边界常见做法是看连续的几帧喝水时头部会有一个低垂并固定的角度吃料时嘴部贴着食槽、有咀嚼趋势。模型学到的是这种视觉分布所以训练集里如果有大量误标样本92.6%这种基线会直接往下掉。睡觉和站立的区分相对容易猪躺着时躯干轮廓明显压低边界框的长宽比会变小。但如果猪圈里有垫料或者地面反光躺着和趴着的边界又会模糊。这类数据集的实际质量往往取决于标注时有没有写详细的规范文档而不是取决于图片总数。2.3 1272张图的体量够不够小数据集的训练策略1272张图对4类行为检测来说属于能训但容易过拟合的体量。以COCO量级做参照常规做法是用YOLOv8官方在COCO上预训练好的权重做迁移学习而不是从零训练。从零训一个检测头通常需要数万张图才能有稳定泛化在这个量级上我一般用yolov8n.pt或yolov8s.pt作为预训练权重前几个epoch冻结backbone之后再全量微调。另一个关键点是验证集怎么切。1272张里如果随机抽20%做验证可能出现某个类别在验证集里完全没有图片的情况。我习惯按类别分层抽样先统计每张图包含哪些行为类别再按类别比例去划分确保验证集覆盖喝、吃、睡觉、站立四类。这一步能避免训练完发现验证集缺类mAP虚高却无法真实反映模型能力。2.4 92.6%是mAP还是分类准确率评估口径先对齐拿到数据集先别急着训练第一个要确认的是平均正确识别率到底怎么算的。如果按目标检测的标准来理解92.6%大概率指的是mAP50也就是IoU阈值0.5下的平均精度。4类目标、1272张图、mAP50在92%左右是一个合理且常见的基线水平。如果它指的是行为分类准确率那就意味着数据集可能还附带每张图的整图标签或者评测时只关心每张图是否检出主要行为。这两种口径之间差别很大。同一个模型mAP5092.6%时分类准确率可能超过95%而准确率92.6%对应的mAP50可能只有80%出头。我一般会在训练前把验证方式固定下来用一个脚本统一计算每张图的预测框与真值框的IoU然后按mAP50和mAP50-95两个维度出报告之后跟别人对比时也只用同一套口径。这样才不会出现你92.6%和我92.6%不是一回事的尴尬。3. 用YOLOv8训练猪行为识别从Ubuntu 20.04环境到第一个权重文件3.1 Ubuntu 20.04搭建YOLOv8 CPU环境如果手头没有GPUUbuntu 20.04上搭CPU版本也能跑通小数据集训练只是慢。CPU训练1272张图yolov8n大概每个epoch需要几分钟总共100个epoch也就是几小时完全在可接受范围内。先建Python虚拟环境# 创建虚拟环境避免和系统Python互相污染 python3 -m venv yolo_env source yolo_env/bin/activate # 安装ultralytics和CPU版PyTorch pip install ultralytics pip install torch torchvision --index-url https://download.pytorch.org/whl/cpuCPU版本的关键是torch要装成CPU专用包否则pip会默认拉一个几个GB的CUDA版本。验证安装是否成功可以执行python -c from ultralytics import YOLO; print(YOLO(yolov8n.pt).model)能正常打印模型结构就说明环境OK。这里最常见的坑是pip默认源下载torch太慢建议换国内镜像源具体方法是在pip install时加-i https://pypi.tuna.tsinghua.edu.cn/simple。提示如果你之后打算在带GPU的机器上训练torch别按CPU版装直接装默认版本即可CPU探索和GPU训练用同一个虚拟环境会省去来回重装的时间。3.2 准备数据集目录结构与训练验证划分YOLOv8要求的目录结构比较固定最好一开始就按它的规范摆好省得到处找图片pig_behavior/ ├── data.yaml ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/如果拿到手的数据集是所有图片一个文件夹、所有txt一个文件夹需要先自己划分。下面这个脚本按比例随机划分并保持同名对应import os, random, shutil src_images pig_behavior/all_images src_labels pig_behavior/all_labels out_images pig_behavior/images out_labels pig_behavior/labels for split in [train, val]: os.makedirs(f{out_images}/{split}, exist_okTrue) os.makedirs(f{out_labels}/{split}, exist_okTrue) names [f.split(.)[0] for f in os.listdir(src_images)] random.shuffle(names) val_count int(len(names) * 0.2) for i, name in enumerate(names): split val if i val_count else train shutil.copy(f{src_images}/{name}.jpg, f{out_images}/{split}/{name}.jpg) shutil.copy(f{src_labels}/{name}.txt, f{out_labels}/{split}/{name}.txt)这里我刻意先shuffle再取前20%做验证集避免按文件名字典序排列时同类图片扎堆。注意txt文件名和图片名必须一一对应后缀也不能写错训练时YOLOv8是按同名去找标注的。如果你的图片是.png或.jpeg记得把脚本里的后缀统一改掉。data.yaml是训练时的唯一配置入口path: /home/user/pig_behavior train: images/train val: images/val nc: 4 names: [drinking, eating, sleeping, standing]这里的names顺序必须和标注txt里的class_id对应。如果不确定原数据集的类别顺序先跑一个小脚本统计所有txt里出现的id集合再按id从小到大反推names千万别凭感觉写。3.3 训练命令与关键参数详解环境就绪后训练命令其实就一行yolo train datapig_behavior/data.yaml modelyolov8n.pt epochs100 imgsz640 batch16 devicecpu如果要用GPU把devicecpu改成device0。训练过程中有几个参数必须理解否则调起来心里没底参数取值建议说明epochs100起步4类小数据集100个epoch足够再多容易过拟合imgsz640默认值原图是1080p时可以试1280但会显著变慢batch16CPU跑16可能内存吃紧OOM就降成8或4devicecpu / 00表示第一张GPU卡modelyolov8n.pt小数据集优先nano不是越大越好epochs的判断标准看val loss是否在后期不降反升。imgsz640意味着模型看到的是缩小后的图像如果猪圈原图里猪头占画面比例很小模型可能漏检远距离目标这时候先跑一版640的baseline再对比1280的效果。batch大小影响的是训练稳定性和显存占用CPU训练主要看内存GPU训练主要看显存。3.4 看训练结果loss曲线和验证指标训练结束后ultralytics会在runs/detect/train/目录下生成weights/best.pt和last.pt以及results.png等图表。看结果不能只看训练loss要看验证集上的mAP50和mAP50-95。# 在训练输出目录下查看每个epoch的指标 cat runs/detect/train/results.csv | head -20results.csv里每一行是一个epoch的训练结果列名包含train/box_loss、val/box_loss、metrics/mAP50等。我一般用这个csv画损失函数曲线图比截图更精确。用matplotlib读csv画val_loss曲线能判断模型在第几个epoch开始过拟合——如果val_loss在80个epoch后持续上升而train_loss还在降那就是过拟合解决方案是提前用best.pt或者加大数据增强。4. 猪行为识别避坑指南类别不平衡、遮挡与标注混乱4.1 睡觉样本过多导致模型偏科现象训练完一验证其他三类mAP都在85%以上唯独站立只有60%。原因统计txt后会发现睡觉和躺卧的图片占了一半以上站立、喝水的样本很少。模型在类别不平衡下会把高频类别学得更准低频类别则被压过。解决先统计每个类别的目标框数量对低频类别做过采样——把含站立、喝水的图片在训练集里重复23份。也可以用YOLOv8的class_weight参数给低频类别更高权重。这类数据集的正确打开方式是先做类别分布体检再动手训练别一上来就跑train。4.2 猪只重叠时边界框互相覆盖现象单个框在单独图片上预测准但一到猪只互相叠压的拥挤场景两个框合并成一个或者在两只猪中间来回跳。原因标注阶段重叠猪只的框如果只标了可见部分模型学到的是半只猪特征而边界框是矩形天然无法区分前景猪和背景猪的边界。重叠场景本来就是目标检测的玄学问题猪圈里尤其严重。解决训练时开启mosaic和mixup数据增强让模型见过更多重叠样本推理时把conf阈值降到0.25左右再用NMS把重叠过高的冗余框压掉。如果还是压不掉就得回到标注层面把完全遮挡、无法判断身份的猪移除或标为ignore而不是硬给一个框。4.3 喝水动作被误判成站立现象预测结果里所有喝的框几乎都落在站立框附近或者干脆不识别喝水。原因喝水和站立在静态图像上高度相似差就差在头部角度和嘴部与饮水器的相对位置。如果标注时把正在靠近饮水器但还没喝也标成drinking模型学到的喝水特征就被稀释了。解决严格按数据集说明里的行为定义重新过一遍标注——只有嘴部接触饮水器或头部有明显低垂吞咽状态的才算drinking。训练时给这类易混类别的图片做针对性裁剪放大让模型专注于嘴部细节。也可以在data.yaml里把drinking和standing的图片分开放在不同子目录便于后面做难例挖掘。4.4 标注文件里出现越界坐标现象训练时报错提示某个box坐标超出了图像边界或者loss变成NaN。原因YOLO格式要求坐标归一化到01但部分标注文件里出现了负值或大于1的数值一般是标注工具导出时没做clip。解决训练前写一个清洗脚本把所有txt逐行读出来用min/max把坐标clip到01之间同时过滤掉宽度或高度小于3个像素的框。import os label_dir pig_behavior/labels/train for fname in os.listdir(label_dir): if not fname.endswith(.txt): continue lines [] with open(os.path.join(label_dir, fname)) as f: for line in f: parts line.strip().split() cid, cx, cy, w, h int(parts[0]), float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) cx max(0, min(1, cx)) cy max(0, min(1, cy)) w max(0.01, min(1, w)) h max(0.01, min(1, h)) if w * 640 3 or h * 640 3: continue lines.append(f{cid} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) with open(os.path.join(label_dir, fname), w) as f: f.write(\n.join(lines))这个脚本我在处理好几个数据集时都会先跑一遍。注意过滤阈值按imgsz640折算如果你把训练尺寸改成1280过滤阈值也要相应放大。4.5 验证集划分造成数据泄露现象训练时验证集mAP有93%模型一部署到新猪圈实测掉到70%。原因划分时没考虑图片来源。同一个猪圈同一个时间段拍的连续帧很可能被同时分到train和val模型在验证集上见过类似的画面val指标虚高。解决按时间段或按猪圈划分而不是随机划分。比如前3天的图片进训练集第4天的图片进验证集。如果数据集本身没有提供拍摄时间信息至少按图片文件名前缀分组把同一批来源的图片放进同一个集合。5. 把92.6%再往上提数据增强、模型大小与损失曲线判断5.1 数据增强怎么设置才不破坏行为语义YOLOv8默认开了不少增强但对猪行为这种动作姿态敏感的任务增强不当会损坏语义。比如水平翻转fliplr对喝水、吃料这类方向无关的行为影响不大但如果猪圈饮水器固定在左侧翻转后位置语义就变了。我的经验是hsv_h、hsv_s、hsv_v颜色抖动参数保持默认即可猪圈光照变化本来就大颜色抖动反而能提升泛化。degrees旋转不要超过10度固定摄像头拍出来的画面不会有太大角度变化。mosaic和mixup在小数据集上强烈建议开启它们相当于免费扩了样本量。下面是一套针对小数据集的增强配置# augment.yaml hsv_h: 0.015 hsv_s: 0.5 hsv_v: 0.4 degrees: 10 translate: 0.1 scale: 0.3 fliplr: 0.5 mosaic: 1.0 mixup: 0.2把配置通过name参数传给yolo train即可。增强参数不是越多越好尤其对行为识别重点是保持动作姿态的可辨识性。我见过有人把degrees开到45度结果模型把倾斜的猪栏立柱当成猪识别率不升反降。5.2 从yolov8n到yolov8m模型大小怎么选小数据集上模型越大越容易过拟合但不代表nano一定最好。我在猪行为数据这类规模的项目上对比过几个模型结论可以参考模型参数量验证集mAP50备注yolov8n约3.2M89%左右训练快过拟合风险低yolov8s约11.2M92%左右平衡点推荐yolov8m约25.9M93%左右提升有限CPU训练慢看YOLOv8网络结构图会发现n到m的差异主要在Backbone和C2f模块的通道数模型变大意味着能学习更细粒度的纹理特征比如嘴部和耳朵的细节。但数据量只有1272张时yolov8m带来的提升通常不超过12个百分点训练时间和显存占用却成倍上涨。如果想在RK3588这类板端部署yolov8n甚至yolov8s的INT8量化更现实训练时就按部署目标选模型避免后期来回换。5.3 画损失函数曲线图判断过拟合还是欠拟合训练完别急着看mAP先画loss曲线。ultralytics生成的results.png里有box_loss和cls_loss曲线但图片分辨率有限我习惯直接用日志数据重画import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs/detect/train/results.csv) epochs range(len(df)) plt.plot(epochs, df[train/cls_loss], labeltrain_cls) plt.plot(epochs, df[val/cls_loss], labelval_cls) plt.legend() plt.savefig(loss_curve.png)如果train_cls持续下降、val_cls在某个点开始反弹就是过拟合信号回去减小epochs或增强mixup。如果两条线都平着走不下降说明学习率太小或模型容量不够可以尝试把lr从默认的0.01调到0.02或者换yolov8s。训练这个猪行为数据集时过拟合通常出现在第80个epoch之后所以epochs100配合早停参数是稳妥组合。5.4 预训练权重与迁移学习的取舍有人问COCO里没有猪用COCO预训练权重对猪行为识别有没有用有用而且帮助很大。COCO预训练让模型学会了通用的边缘、纹理和物体结构特征这些对猪一样适用。差别只在最后的检测头——COCO的输出是80类我们的输出是4类所以迁移时要让ultralytics自动裁剪最后一层。如果坚持从零训练torchvision和ultralytics都支持随机初始化但代价是收敛慢、精度低。1272张图从零训出来的模型往往还不如直接用yolov8n.pt微调30个epoch的效果。我的建议是第一次训练用官方权重先把baseline跑出来之后如果想对比从零训练再用modelyolov8n.yaml加载随机权重但不要对精度抱太高期望。6. 部署到RK3588板端从PyTorch权重到RKNN实时推理模型训完最终要落到猪场监控上。RK3588是目前做边缘端行为识别比较常见的板子它不直接吃PyTorch权重需要先转ONNX再转RKNN。yolo export modelruns/detect/train/weights/best.pt formatonnx imgsz640 opset12这一步要注意opset版本RKNN工具链对opset12支持比较好opset太高会报不支持算子。转出的onnx再用rknn-toolkit2转成rknn格式。如果做INT8量化需要准备几十张代表性图片做校准直接在1272张里随机抽容易掉点最好是覆盖白天、夜间、喂料前后等不同光照和活动状态的图。板端推理的几个关键参数参数建议值说明输入分辨率640和训练保持一致板端改320会明显掉精度conf阈值0.3低于0.3输出大量重叠框高于0.5漏掉遮挡目标NMS放CPU端NPU上只跑模型推理NMS用opencv或自写代码处理量化类型INT8RK3588的NPU对INT8支持最好FP16精度高但速度慢我在RK3588上跑yolov8n的INT8量化单路640×640大概能到2030ms一帧四路监控串行处理勉强够用。如果追求更高帧率可以把输入降到480同时把conf阈值从0.3调到0.35牺牲一点召回换速度。这套流程走完你会发现猪行为识别真正花时间的不是训练而是数据和部署这两头数据标注规范决定了模型上限部署时的量化校准决定了实际表现。我自己的习惯是拿到任何行为识别数据集先花半天做类别分布和标注质量体检再决定要不要继续投入时间——这是若干次训练翻车换来的经验希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网