基于YOLO的猫情绪识别:3200张宠物行为数据集构建与训练实践

发布时间:2026/9/30 13:49:59
基于YOLO的猫情绪识别:3200张宠物行为数据集构建与训练实践 做宠物摄像头项目时我卡在一个很朴素的问题上猫到底处于什么状态如果只是“有猫/没猫”用现成人脸检测模型就行但客户要的是“放松、警觉、紧张、害怕、玩耍”这种细粒度情绪反馈。翻遍公开数据集猫狗二分类一大把品种识别也不少专门做猫情绪行为标签的却几乎没有。于是我整理了一套 3200 张 YOLO 宠物行为数据集用来训练基于 YOLO 系列检测器的猫情绪识别模型。这篇文章的核心是把数据集的设计逻辑、标注规范、训练过程和排错经验完整写下来给准备从零做小型行为检测方案的朋友当参考。先说下数据集的定位不是把猫框出来这么简单而是让模型在输出目标框的同时给出行为/情绪类别。从工程角度看这套数据和 YOLO 的任务要求刚好对齐——目标检测天然具备“定位 分类”两个输出不需要额外接分类头。3200 张图对于表情/姿态这类中粒度行为识别足够做 MVP。1. 先说结论3200 张图做猫情绪检测够不够1.1 这个数据集到底解决什么问题很多入门的同学会疑惑猫情绪检测不是可以用图像分类模型吗输入一张猫脸输出情绪类别。但在真实场景里问题没这么简单。首先宠物摄像头里猫的位置不固定猫可能只占画面的一小块直接用分类器会连背景一起学进去其次我希望系统在“无猫画面”下保持静默在有猫时才触发情绪分析这本质上就是一个目标检测任务。所以我选择用 YOLO 来做模型先产生一个边界框把猫定位出来再做类别判断。3200 张数据里每张图都对应一个 txt 标注文件标记了猫的位置和情绪标签。这套结构直接由 YOLO 格式规定能省掉一大部分数据处理步骤。1.2 3200 张规模怎么“够用”很多做深度学习的朋友会习惯性追求大规模数据动辄五万十万张这在小团队自研项目里其实不现实。我这套“猫情绪检测数据集”定位是快速验证和场景化训练3200 张是一个经过权衡的数量级。情绪识别是相对粗粒度的分类不需要像人脸识别那样处理超级细的类间差异迁移学习帮了大忙使用 YOLOv8 或者 YOLOv5 在 COCO 上的预训练权重模型已经具备了基础的物体边缘、纹理、形状感知能力我们只需要微调最后几层和部分骨干网络每张图包含一只或多只猫、含背景信息、含姿态变化实际信息量远超过单价 3200 这个数字。3200 张图并不意味着每张只有一只猫。数据集中有部分图包含两只甚至三只猫按目标框数量算可用于训练的样本目标数大概在 3800 个左右。加上训练时的 Mosaic、HSV、随机缩放等增强模型见过的形态组合是非常丰富的。2. 数据集从 0 到 1情绪怎么定义、标注怎么落盘2.1 情绪类别划分5 类比“开心/难过”更可标注做情绪数据集最怕定义模糊。如果你让标注员区分“开心”和“兴奋”大概率每人给一个标准。我在设计最终数据集时参考了宠物行为学里一些相对可观察的指标而不是人的主观情绪投射。类别ID类别名视觉行为线索标注样本量0relaxed放松眼睛半闭、耳朵自然、尾巴慢摆、身体舒展8201alert警觉耳朵向前/转动、瞳孔放大、身体定住7602defensive防御/紧张飞机耳、弓背、炸毛、尾巴竖直6403fear害怕压低身体、夹尾巴、视线回避、后退4304playful玩耍伏低身体、尾巴快速摆动、扑咬前的姿势550这套类别体系避开了“难过/开心”之类抽象情感改用可观察的姿态和动作组合来解释。标签名最终定为英文是为了后续直接喂给 YOLO 的 names 配置减少转换成本。样本量分布上我把害怕类刻意控制在 430 张因为它和其他类别在视觉上有一定重叠如果强行加太多模糊样本反而会拉低整体 mAP。2.2 文件目录与 YOLO txt 标注格式整个数据集按照 YOLO 训练惯例组织结构是下面这个样子cat_emotion_dataset/ ├── images/ │ ├── train/ # 2600张 │ └── val/ # 600张 ├── labels/ │ ├── train/ # 对应同名txt │ └── val/ └── cat_emotion.yaml训练集和验证集按 8:2 划分验证集覆盖全部 5 个类别并且尽量保证验证集里出现的新场景不在训练集里出现过。比如同一只猫在不同光线下的照片我只把其中一部分放训练集另一部分放验证集这样指标才不至于虚高。labels 里每个 txt 文件与图片同名例如relaxed_023.jpg对应relaxed_023.txt。文件里每行代表一个标注框格式为类别ID 中心点x比例 中心点y比例 框宽比例 框高比例拿一张具体的图举例0 0.5102 0.4335 0.2781 0.3412 2 0.1265 0.3100 0.3521 0.4120这表示该图有两个目标框第一只猫是 0 类放松第二只猫是 2 类防御。坐标全部归一化到图片宽高这跟传统的 x1、y1、x2、y2 格式不一样实测中转换时最容易漏的就是没有归一化导致训练 loss 直接飘到 NaN。2.3 标注过程中我踩的坑标注这套数据花了我大概两周的碎片时间。第一个坑是框的粒度控制。一开始我习惯把整只猫框进去结果发现 YOLO 模型对猫尾的识别很不稳定因为尾巴的方向变化大且经常超出主体区域。后来我重新调整标准目标框包含身体主干和头部尾巴如果完全伸展且不贴近身体就不强行包进去。这样训练损失更平稳而且吹毛求疵地讲情绪判断主要依赖头耳和前半身尾巴是辅助线索。第二个坑是极短时间内的重复帧。很多视频抽帧得到的图片相邻帧的光线和姿态几乎一样等于标注了两张几乎一样的图。这种重复数据会让验证集指标虚高。我处理的方法很简单用图像感知哈希对候选图片做去重相似度高于 0.95 的直接剔除只保留一张。第三个坑和文本标签有关不要用中文标签也不要在类别名里带空格。YOLO 的配置文件对 names 列表的读取非常敏感我早期填过一个名字叫defensive_fear模型训练没问题但导出 ONNX 后推理结果和类别对不上排查起来极其费时。建议全小写英文必要时用下划线连接。3. 用 YOLO 训练猫情绪的实操记录选型、配置与损失函数3.1 为什么最终用 YOLOv8先说结论选 YOLOv8 不是因为它在精度上碾压老版本而是因为我需要一套能快速迭代、自带数据增强和评估可视化的工作流。YOLOv5 和 YOLOv8 在小数据集上的差距并不大甚至在某些任务上 YOLOv5 更稳但 YOLOv8 在训练管线上更省心。它默认开启了 mosaic、mixup、随机 HSV、平移缩放等增强不需要额外写预处理代码。它的模型设计里把 anchor-free 和 anchor-based 的优势做了整合对小目标猫脸检测也比较友好。尤其是猫在画面里占比较小时v8 的解耦检测头比 v5 的耦合头更容易收敛。如果你想做实时部署YOLOv8 也能一键导出 ONNX/TensorRT不折腾。老版本还有 Anchor 大小需要考虑在自定义数据集上可能需要手动聚类生成合适的 AnchorYOLOv8 的解耦头方式让 Anchor 不再是主要超参数。建议从yolov8m.pt权重开始微调而不是 n 或 s 起步。m 模型在 3200 张数据上的过拟合风险可控特征提取能力却明显好于 n。3.2 数据集 yaml 和训练命令先提供一个最小可用的数据集配置# cat_emotion.yaml path: /path/to/cat_emotion_dataset train: images/train val: images/val nc: 5 names: 0: relaxed 1: alert 2: defensive 3: fear 4: playful训练命令我用的是yolo detect train \ datacat_emotion.yaml \ modelyolov8m.pt \ epochs200 \ imgsz640 \ batch16 \ lr00.001 \ patience30这里解释一下参数选择。imgsz640是均衡速度和精度的常用值如果你希望模型更关注猫的耳朵角度等细节可以上到 768代价是显存和推理时间增加。对于带尾巴、四肢伸出等细长姿势的猫来说稍微提高分辨率确实有一点收益但 640 基本够用。学习率 0.001 是我在踩坑后固定下来的。YOLOv8 默认的自适应学习率在小数据集上容易飙得过头导致早期训练波动巨大。稳妥的做法是直接用固定学习率配合patience做早停。patience30表示连续 30 个 epoch 验证集指标没有提升就停止训练实际中往往在 130 到 160 个 epoch 之间才会触发早停。3.3 损失函数在猫情绪任务里怎么起作用YOLOv8 的损失函数由三部分组成分类损失、边界框回归损失、DFL 分布损失。很多同学习惯把这三大块打包理解但在行为数据上有必要拆开想一想。分类损失用的是 BCE二分类交叉熵它让每个检测框输出一个 5 维的概率向量分别对应 5 个情绪类别。实际操作中类别重叠的问题很常见一只弓背炸毛的猫它可能同时具备防御和害怕两种特征。BCE 允许一个框同时输出多个类别的概率这就比 Softmax 多任务强一点。最终推理时我们用conf0.5过滤低置信度结果如果defensive和fear的概率分别是 0.7 和 0.6系统会输出两个候选框再由后处理合并。边界框回归损失负责把猫框得更准。这里我补充一点为什么这对情绪识别很重要如果框只框住猫头模型会丢失身体姿态信息如果框扩大太多背景干扰又会混进来。回归损失的作用就是让模型自动找到信息最充分的框范围。我在实验中发现框住“头身体主干”比只框住头部的 mAP 高接近 5 个百分点。DFL 损失是对边界框坐标做精细分布估计的机制。在猫尾巴甩动、四肢伸展这类边界不清晰的目标上DFL 能减少框的抖动让检测框边界不那么容易被毛发的边缘带偏。3.4 数据增强里必须和 Mosaic“和解”的地方YOLOv8 默认开启 Mosaic 增强将四张图拼成一张训练。这个策略在通用检测任务上效果显著但情绪行为识别里要小心处理。我第一次训练直接使用默认参数验证集上 mAP 在约 80 个 epoch 时突然掉了一截。后来排查发现是 Mosaic 把四只完全不同的猫拼在一起模型被迫去学习跨图的碎片化特征导致行为语义被切碎。猫的情绪特征依赖整体姿态尤其是弓背、飞机耳这些线索如果被中间线切开反而变成有害噪声。我最终的做法是前 100 个 epoch 开启 Mosaic之后关掉再训练 30 个 epoch 让模型在真实比例的数据上重新校准。在命令行里可以通过mosaic1.0和mosaic0.0控制或者直接分两阶段训练。这比一直开着 Mosaic 效果好也比完全关掉收敛慢、泛化弱。折中方案是保留 Mosaic 但把拼接数量从 4 降到 2也就是只用两张图拼接语义破坏明显减轻。4. 那两个把训练卡住的问题BN 崩溃和混淆矩阵“总和不唯一”4.1 BN 崩溃现场怎么回事、怎么救训练中我遇到的最典型异常是 Batch NormalizationBN崩溃表现为训练 loss 从 1.0 附近突然跳到 nan或者验证集 mAP 在某个 epoch 之后持续归零。BN 层在 YOLO 骨干网络中无处不在它通过统计当前批次数据的均值和方差来归一化特征。什么时候会崩就是当批次内样本数量太少或学习率设置过大时统计量变得极不稳定。我的第一次崩溃场景是为了省显存把 batch 调成 4学习率用默认 0.01结果在第 7 个 epoch 就出现 loss 升高第 12 个 epoch nan。原因很简单batch4 时BN 层每个 step 看到的只有 4 张图的统计量而这些图可能是三只放松猫加一只害怕猫分布差异极大归一化参数被拽得来回抖动最终训练崩溃。解决办法有三步第一batch 提到 16让 BN 统计量更稳定第二学习率降到 0.001配合预热第三重新使用预训练权重而不是随机初始化。这三步做完之后崩溃问题再没出现过。如果 batch 大小受显存限制无法提升另一个技巧是冻结前几层骨干网络训练。在 Ultralytics 里可以用freeze10冻结模型前 10 层这样 BN 层的统计量不会因为训练初期的混乱而崩坏等后半段再解冻微调。这个方法对只有单张 GPU、显存吃紧的开发者格外实用。4.2 混淆矩阵总和为什么“对不上”以及正确的读法训练结束后你会在runs/detect/train/confusion_matrix.png看到一张 6×6 的混淆矩阵5 个情绪类别 背景。很多同学第一反应是把每一行加起来和验证集样本数做对比会发现“总合不唯一”矩阵最后一行的数字和前面各行的汇总对不上。这不是数据集错误而是目标检测混淆矩阵的计数规则和普通分类不同。目标检测的混淆矩阵里每个真实目标框要和预测框做 IoU 匹配。如果一个真实框同时匹配到多个预测框只有置信度最高的那个算 True Positive其他预测框会被计入错检如果一个预测框没有匹配到任何真实框则落入背景行。这意味着同一个目标可能会同时引发真实类别的正确计数和背景类的误判计数因此行与列的总和并不守恒。我在实际实验里遇到过具体的例子验证集里有一张图包含两只猫一只放松一只警觉。模型正确框出了放松猫却把警觉猫重复框了两个框一个 IoU 0.63 算正确另一个 IoU 0.44 落在置信度较低的重复位置被计入背景误检。混淆矩阵里就会出现 relaxed 列 1、背景列 1推送回真值背景总数却不变。所以读混淆矩阵时不要追求“行和等于背景样本数”。你应该关注的是对角线上每一类的数值以及哪些类之间最容易互相混。我这份数据集中fear和defensive之间的互相混淆最明显因为压低身体和弓背在部分角度下确实相似。后续改进方向是增加这两类的边界样本而不是去检查矩阵加总。5. 从 best.pt 到真实摄像头指标、导出与时序平滑5.1 我只看几个核心指标P、R、mAP50模型训练完成后Ultralytics 会输出 Precision、Recall、mAP50、mAP50-95 等指标。很多新手只盯着 mAP50-95觉得越大越强但对行为检测项目来说mAP50-95 并不完全反映落地性能。我习惯构建一张分类别评估表类别PrecisionRecallmAP50relaxed0.910.890.94alert0.880.850.91defensive0.870.840.90fear0.810.760.83playful0.860.820.89overall0.870.840.91从这张表里能读出的关键信息是fear 类的召回率明显偏低。也就是说有些害怕状态被模型看成了 calm或者被漏检。为什么更在意 recall 而不是 precision因为宠物摄像头场景里漏报一只害怕的猫可能意味着用户错过应激事件而把 relax 误判成 defensive最多是多发一条提示。所以在推理阶段我针对 fear 类把置信度阈值单独下调到 0.4其他类别保持 0.5。mAP50 是更贴近这类任务的指标因为它对边界框的要求比较宽松只要框中心和真实目标重叠程度尚可就判定为正样本。宠物检测不需要像素级精确mAP50 是更合理的评价标准。5.2 导出为 ONNX/TensorRT 并在轻量设备上跑最终要部署到嵌入式设备我建议直接导出 ONNX 再转 TensorRT而不是用 PyTorch 模型跑推理。PyTorch 模型的推理速度和内存占用在树莓派、Jetson 这类设备上完全不能接受。导出 ONNX 的命令很简单yolo export modelbest.pt formatonnx opset12 simplifyTrue导出时注意两个细节一是opset不要贪新选择 12 左右的兼容性比较好二是simplifyTrue可以移除一些冗余计算节点让 ONNX 在 CPU 或移动端运行时更快。如果在 Jetson 设备上可以继续转 TensorRTtrtexec --onnxbest.onnx --saveEnginebest.engine --fp16TensorRT 引擎通常能比 ONNX 再快 30% 到 50%。我测试过用 YOLOv8n 导出的引擎在 Jetson Orin Nano 上推理一帧 640×640 图耗时大约在 18-25ms 左右能勉强跑到 30FPS。如果换更大的模型就要牺牲帧率来换取准确率或者在摄像头端降低检测频率。5.3 帧级检测不能直接用加一阶时序平滑最后一步也是最容易被忽略的一步单帧检测结果在视频里会剧烈抖动。同一只猫在连续几帧里被识别成 relax、alert、relax你会看到情绪状态在界面上来回跳这种体验很糟糕。解决方案是维护一个固定长度为 5 的队列对最近几帧的情绪结果做投票from collections import Counter, deque frame_results deque(maxlen5) def update_status(detections): if detections: frame_results.append(detections[0].boxes.cls[0].item()) counter Counter(frame_results) top_label, top_cnt counter.most_common(1)[0] if top_cnt 3 and top_label ! current_status: current_status top_label return current_status这段逻辑等于要求某一个情绪在 5 帧里出现至少 3 次才认可状态变化。实测能显著降低误跳变。同时我也加入了置信度平滑如果当前帧的最高置信度低于 0.5就不把该帧结果存入队列等于给检测器一个“犹豫权”。有一点要说明时序平滑会增加响应延迟5 帧窗口在 30FPS 下大约延迟 170ms对于人眼观察宠物状态来说完全可以接受。如果你要接入自动喂食器或逗猫棒这类需要快速响应的设备窗口长度可以缩短到 3 帧。最后想分享的经验是情绪识别模型的成败一半在数据标注策略一半在训练参数的稳定性。3200 张的“猫情绪检测数据集”绝不是一个小到可以被忽略的规模只要类别定义清晰、标注边界统一、训练流程稳健它能撑起一个可落地的宠物行为感知系统。后续扩展方向也很明确增加同一只猫的不同机位视角加入不同品种的样本再引入时间序列信息用若干帧的上下文做状态判断。恰好这套数据集的 txt 格式是 YOLO 标准结构后续做视频级行为识别时只需要按时间戳拼接检测结果即可不需要返工整理。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询