资讯详情

YOLO猫狗检测数据集:4300张图片从整理到训练实战

📅 2026/10/2 10:41:36 | 华诺云谱 👁 阅读
YOLO猫狗检测数据集:4300张图片从整理到训练实战
这份猫狗检测数据集其实是被我自己逼出来的。当时想把手里的YOLO环境完整撸一遍从数据准备、标注、训练到导出部署全流程打通结果发现宠物识别这种入门级目标检测任务居然很难找到一套干净、统一、能直接喂给ultralytics的训练数据。有的数据集是COCO格式有的是VOC格式类别还经常把猫、狗和其他动物混在一起光转换格式就能折腾一下午。后来干脆按自己的标准整理了一份4300张的YOLO格式宠物识别数据集猫狗类别平衡标签文件和data.yaml一次性配好扔进YOLO就能训。这篇文章把这套数据集的整理思路、YOLO标注格式、训练配置以及实操中踩过的坑完整交代一遍适合准备入门目标检测、想用自己的数据跑通猫狗宠物识别模型的朋友。1. 为什么猫狗检测是最佳练手场景1.1 类别辨识度高不代表“好检测”很多人一听“猫狗检测”就觉得简单毕竟猫和狗长得很不一样看到一张图就能立刻分辨。但在目标检测里“认得出来”和“检得出来”是两码事。猫狗虽然类别差异大但它们在画面里的姿态极其多变有趴着的、跳起来的、背对着镜头的、缩成一团的还有直接把自己塞进沙发缝里的。姿态变化直接导致检测框的宽高比波动很大从接近正方形的正面照到又长又扁的侧面卧姿模型都要能稳住。再加上光照、遮挡和背景干扰猫狗检测对初学者来说是最合适的入坑项目难度适中没有让人劝退但又能把你逼着去理解标注格式、数据分布、过拟合和模型调参这些核心概念。很多人在COCO上训练半天根本看不到自己的操作对结果有什么影响换成猫狗数据集之后效果好还是坏一眼就能看出来。这也是我整理这份数据的初衷给0基础的朋友一个能快速上手、又能学到真东西的训练样本集。1.2 这份数据集想解决什么问题市面上不缺猫狗图片缺的是“整理好”的数据。我在前期调研时下载过好几个公开数据集问题主要集中在三方面一是标注格式五花八门有XML的VOC格式、有JSON的COCO格式就是没有现成的YOLO txt格式二是类别定义混乱有些数据集把猫狗拆成七八个细分类训练目的完全不同三是数据质量参差不齐大量重复图、模糊图、水印图混在里面直接训练简直是灾难。所以这份4300张的宠物识别数据集从一开始就定了三个目标。第一格式直接对齐YOLO官方约定解压就能训练不搞二次转换第二类别严格只有cat和dog两类不做品种细分专注解决“检测出宠物位置并区分猫狗”这个基础问题第三数据经过清洗和平衡剔除了绝大多数低质量样本猫狗数量接近1比1避免模型学到类别偏差。我的实际体验是数据干净比数据量大重要得多一份4300张的高质量数据训练效果往往好过随意收集的上万张照片。2. 4300张YOLO宠物识别数据集是怎么整理出来的2.1 数据构成与类别分布这份数据集最终保留4300张可用图片其中猫约2120张、狗约2180张整体比例接近1比1。所有图片统一转换为JPG格式RGB三通道标注文件全部是YOLO标准的txt格式。整个数据集的标签框总数在6900个左右也就是说平均每张图有1.6个目标框部分图片中有两三只宠物同时出现这对模型学习多目标检测很有帮助。收集过程是这样的我从开放图库和公开数据源里筛选了一大批候选图片再用爬虫补充了一部分场景差异比较大的照片比如户外街道、夜晚灯光、逆光剪影等避免模型只见过室内明亮环境。候选图一共有7600多张经过清洗和标注后剩下4300张。初始收集量远大于最终保留量这很正常做数据集一定要舍得扔掉坏样本硬留下来只会拖累训练。最后的4300张按8比1比1划分为训练集3440张、验证集430张、测试集430张每个子集内部都保持着猫狗接近1比1的分布。2.2 清洗标准什么样的图片被淘汰了数据清洗是这整个过程中最耗时、也最体现经验的部分。我总结了一套简单但有效的淘汰标准供大家参考。第一目标过小的图片直接不要。如果宠物占整张画面的面积比例小于2%标注出来的框很小对YOLO学习目标特征几乎没有正向帮助反而会干扰anchor匹配。第二严重模糊和运动模糊的图片淘汰。这类图片人眼都很难看清轮廓标注框全靠猜训练时模型学到的是错误纹理。第三重复图用感知哈希算法去重只保留清晰度最高的一张避免同一只猫在不同角度下被反复计入导致模型过拟合到特定个体。第四带大面积水印且水印正好盖住宠物身体的图片不保留水印的纹理容易被模型误当成宠物特征。还有一个容易忽略但很重要的点EXIF旋转信息。很多手机图片虽然看起来是正的但原始数据里带有旋转标记如果标注工具没有正确处理训练时YOLO读取图片会自动转正但坐标框是按旋转前的图像标注的结果就是框全部偏移。我在清洗阶段把所有图片都经过一次方向转正并重新保存彻底规避这个问题。2.3 标注策略什么时候该标什么时候不该标标注策略直接决定模型的上限。我最初踩过坑把猫脸、狗头单独标出来训练结果模型只能框住头部整个身体框不全。后来统一改为标注宠物完整身体区域包括尾巴算在内除非尾巴被遮挡得只剩末端。这个策略对检测效果影响非常大因为YOLO训练时更偏向学习一个完整的整体轮廓而不是局部的零散特征。遇到遮挡情况时我的原则是“看得见多少标多少”。如果一只狗被桌子挡住了一半就标注可见的上半身区域而不是强行估一个完整框。这样模型能学到部分遮挡下的检测能力。对于同一张图里有多只宠物互相紧贴的情况比如两只猫挤在一起睡觉我的做法是分别标注两个框即使两个框重合度很高也不要合并。合并框会让模型学到一个模糊的“猫群”概念而不是清晰的“猫”概念。实测下来这样的标注策略在验证集上mAP能明显拉开差距。3. 必看YOLO标注格式与数据集目录结构怎么写3.1 YOLO txt标注的真实格式YOLO格式的标注文件是纯文本每一行代表一个目标框格式是“class x_center y_center width height”。其中class从0开始计数这个数据集里0代表cat1代表dog。x_center、y_center、width、height全部归一化到0到1之间计算方式是框的绝对像素坐标除以图片宽高。举个例子一张宽800像素、高600像素的图片里有一只猫框的左上角坐标是(100, 150)右下角坐标是(500, 450)。那么框的实际宽度是400像素高度是300像素中心点x坐标是300中心点y坐标是300。归一化之后就是x_center300/8000.375y_center300/6000.5width400/8000.5height300/6000.5。对应txt内容就是“0 0.375 0.5 0.5”。这类计算看似简单但一旦搞混绝对坐标和归一化坐标训练出的模型要么loss飞起要么框全部跑偏属于新手最容易出错的环节。图片文件和标签文件的命名必须一一对应比如图片叫cat_001.jpg标签必须叫cat_001.txt后缀可以不同文件名主体必须相同。如果一张图没有目标那么标签文件可以不存在YOLO训练时会自动跳过这张图但我个人建议保留一个空txt文件更便于排查。3.2 目录结构布局与数据划分细节标准的ultralytics目录结构是这样的每个子集都严格分离图片和标签dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/图片放在images目录下对应的txt标签放在labels目录下train配对trainval配对val。这个结构非常关键YOLO会自动到labels目录下找同名txt如果目录层级搞错训练时就会报“Label not found”的警告。划分数据时我按文件名列表做随机切分固定随机种子保证每次划分结果一致。需要注意一个容易忽略的坑如果数据是从视频抽帧得到的必须把同一段视频的帧全部划分到同一个子集不能随机打散。否则训练集和验证集里会出现来自同一个视频的相似帧造成数据泄漏验证指标虚高实际部署效果跟不上。我这份数据虽然大多是单张照片划分时仍然按来源分组处理确保没有同一场景的不同图片同时出现在训练集和验证集里。3.3 一个能直接用的数据划分与校验脚本我把自己用的脚本简化后放在这里它做两件事第一按比例划分图片并同步标签文件第二校验所有标签文件里的坐标是否越界、类别是否超出范围。运行环境就是Python 3不需要额外依赖。import random import shutil from pathlib import Path base Path(dataset) train_ratio 0.8 val_ratio 0.1 all_images list((base / images / all).glob(*.jpg)) random.seed(42) random.shuffle(all_images) train_count int(len(all_images) * train_ratio) val_count int(len(all_images) * val_ratio) splits { train: all_images[:train_count], val: all_images[train_count:train_count val_count], test: all_images[train_count val_count:], } for split_name, images in splits.items(): img_out base / images / split_name lbl_out base / labels / split_name img_out.mkdir(parentsTrue, exist_okTrue) lbl_out.mkdir(parentsTrue, exist_okTrue) for img in images: shutil.copy2(img, img_out / img.name) label base / labels / all / (img.stem .txt) if label.exists(): shutil.copy2(label, lbl_out / label.name) # 校验标签 for split_name in [train, val, test]: label_dir base / labels / split_name for txt in label_dir.glob(*.txt): for line in txt.read_text().strip().splitlines(): parts line.split() cls int(parts[0]) coords list(map(float, parts[1:5])) if cls not in (0, 1): print(f{txt.name}: 类别id异常 {cls}) if any(c 0 or c 1 for c in coords): print(f{txt.name}: 坐标越界 {coords})如果脚本运行后没有任何输出说明文件都正常。路径中的“all”目录是我在整理阶段统一存放未划分数据的中间目录最终发布时已经整理成标准结构不需要大家手动去重建但理解这个过程对自建数据集有参考价值。4. 0基础也能复现用这份数据集训练猫狗检测模型4.1 环境配置YOLOv8/ultralytics版现在训练YOLO大多走ultralytics这条链路它统一了YOLOv8和后续新版本的训练、验证、推理接口。0基础小白的推荐安装方式是用miniconda建一个干净的Python 3.10环境先安装PyTorch再安装ultralytics。CUDA版本的PyTorch安装命令要根据自己的NVIDIA驱动版本来建议先从PyTorch官网复制对应命令保证GPU可用。conda create -n yolo python3.10 -y conda activate yolo pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 pip install ultralytics装完之后可以跑一句yolo看是否进入帮助界面。如果不想折腾虚拟环境直接用pip装ultralytics也能跑CPU训练但GPU和CPU的训练速度差距接近几十倍哪怕只是入门练手也建议至少搞到一张6GB显存以上的NVIDIA显卡。这张数据集训练YOLOv8n6GB显存完全够用。4.2 data.yaml配置文件的写法ultralytics训练时靠一个YAML文件告诉模型数据在哪里、有几类、类名是什么。我把这份数据集配套的data.yaml写成这样path: /your/abs/path/dataset train: images/train val: images/val test: images/test nc: 2 names: [cat, dog]这里path写数据集根目录的绝对路径train、val、test都写成相对路径这样在目录结构和训练命令之间切换时不容易出错。nc是类别数量必须等于2names列表里的顺序要和标注文件里的class编号一一对应即0对应cat1对应dog。如果names顺序写反了训练依然能跑但训练出来的模型会把猫叫成狗、狗叫成猫排查起来特别迷惑。还有一个细节测试集不是训练必需的ultralytics允许在data.yaml里只写train和valtest留空。但对这个4300张的数据集而言我建议保留test字段因为用完全没参与训练和验证的图片做最终评估得到的mAP才真正反映模型泛化能力。4.3 训练命令与关键参数说明我把典型的训练命令写出来逐个解释参数含义yolo detect train \ data/path/to/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ patience20 \ device0modelyolov8n.pt表示从官方预训练权重开始继续训练这叫迁移学习对小数据集尤其有效。n是nano版本参数量最小、训练最快猫狗检测任务完全够用。如果显存紧张就把batch调小到8同时可以考虑把workers调低。imgsz640是训练分辨率YOLO官方默认值对猫狗这类中大型目标很合适。如果图片里宠物偏小可以把imgsz提高到768或928但训练时间会相应增加。epochs100对4000多张图来说足够配合patience20的早停机制如果连续20轮验证集指标没有提升训练会自动停止省时省力。我用默认增强训练时通常在60到80轮左右就能看到验证集mAP收敛100轮已经从充分了。4.4 训练结果怎么读、指标怎么看训练结束后ultralytics会在runs/detect/train目录下生成weights文件夹里面有两个文件best.pt和last.ptbest.pt是验证集表现最好的权重推理时选它准没错。同时生成的results.csv可以用Excel或Python打开绘制loss曲线和mAP曲线。以这个4300张数据集为例我实际训练YOLOv8n的效果是验证集mAP50稳定在0.97以上mAP50-95在0.90左右单张图片的平均推理耗时在几毫秒量级。这个成绩并不夸张因为猫狗检测类别少、目标尺度大加上数据质量干净如果mAP50连0.9都上不去大概率是数据或训练设置出了问题而不是模型能力不行。不过指标要分开看。mAP50只看框和真实框的IoU是否大于0.5相对宽松。mAP50-95则对框的精确位置要求高得多更能反映定位质量。训练过程中如果发现mAP50很高而mAP50-95偏低说明框的位置经常有偏移可以考虑提高imgsz或检查标签框是否标注得足够贴合。5. 训练宠物识别模型时常见的5类坑和自查方法5.1 类别id错乱预览时猫狗对不上这是新手最容易遇到也最难发现的坑。表面上看训练正常loss在下降mAP在上升但预测结果一显示猫的框标注为狗狗的框标注为猫。原因基本是两个一是标注工具导出时把names按字母序排了dog排到了0、cat排到了1二是data.yaml里names顺序和标注文件的id对不上。自查方法很简单训练前随机抽几张val图片在标注文件里读取第一行的class编号到data.yaml里查对应的names同时人工确认图片里的真实类别三处一致才算通过。我在数据发布前已经用脚本统一校验过保证cat是0、dog是1避免大家踩这个坑但如果你之后自己补充了标注数据一定要重新过一遍这个检查。5.2 标签文件缺失或坐标越界另一个常见问题是部分图片缺失标签文件或者标签文件里的坐标值超出了0到1的范围。坐标越界通常发生在人工标注后忘记归一化或者图片在标注后被裁剪过但标签没有重新计算。我的脚本已经检查了坐标是否在0到1之间但如果你用Roboflow这类在线工具导出偶尔会出现浮点精度问题导致坐标为1.0000004之类的微小越界这种一般不影响训练但严格起见建议提前处理。给一个极端的提醒YOLO训练时如果标签坐标异常通常不会直接报错而是把这张图标记为“corrupted”并在日志里警告同时跳过该图对应损失。很多人根本没注意这些警告导致模型在脏数据上训练表现忽上忽下。建议训练前看一眼日志里有没有大量warning。5.3 loss不收敛或剧烈震荡怎么办排除了数据问题后loss不收敛大概率是超参问题。常见表现有三种一是box_loss和cls_loss从头到尾不降先检查学习率默认0.01对小数据集偶尔偏激进可以加上lr00.005试试二是训练集loss持续下降但验证集mAP不动这是过拟合信号可以增加数据增强强度或减少训练轮数三是loss曲线震荡特别厉害优先检查batch size是否太小导致BN统计量不稳定小显存用户建议batch8以上并开启梯度累积。还有一个U型坑很多人一上来就换YOLOv8x这类大模型结果4300张图根本喂不饱验证集指标反而不如nano版。遇到这种情况不要硬调先用小模型把pipeline跑通确认无误后再考虑加大模型。模型规模和数据量不匹配是猫狗检测里非常常见但又容易被忽视的问题。5.4 小目标漏检和推理卡顿的排查方向如果训练出的模型对大猫大狗识别很好但照片里宠物离得很远、只占画面很小一部分时经常漏检可以从两个方向入手。第一训练时适当放大imgsz到768或928让模型在输入中看到更大的目标特征第二确认训练图片里的最小目标比例如果数量太少建议补充一部分远距离拍摄的猫狗照片重新训练。推理卡顿的问题很多时候不在模型本身而在数据前后处理。用Python接口循环处理大量图片时读图和缩放占用的时间往往比模型推理还多。如果追求实时性建议用yolo export把best.pt导出为ONNX或TensorRT格式部署时配合GPU推理吞吐能提升好几倍。在T4这类GPU上做1080p视频流检测时很多人的关注点都放在“模型能跑多少fps”但实际瓶颈往往出现在视频解码和图像缩放上先把前后处理优化好再单独测模型算力这个顺序我建议反过来。5.5 自己补充新数据时的标注一致性这份数据集后续使用过程中大家很可能想加入自己的猫狗照片。补充数据时最容易破坏一致性的是标注框风格。有人习惯把框画得很紧正好卡在宠物毛发的边缘有人习惯留一点边距把毛发阴影也包进去。两类风格混在一起模型学到的框反而“歪歪扭扭”。我在标注时统一采用“贴住主体但不裁切毛发”的原则补充标注时建议保持相同标准。另外新增数据后必须重新执行数据划分脚本确保新增图片被正确分配到train、val、test三组不能图省事把所有新图片直接丢进训练集。如果新增图片和现有图片存在大量重复记得先跑一遍去重否则训练集里同一只猫反复出现验证集指标看着漂亮部署时却对没见过的新个体表现不佳。最后分享一点个人体会数据集的干净程度永远比数量重要。我当年训练猫狗检测模型用过两万张混杂图片效果反而被这份4300张清洗过的数据甩开一截。原因很简单模型学到的是数据里的规律而不是数据本身脏数据里的错误标注就是一种噪声规律。这个项目做完后我又顺手把数据划分、标签校验脚本沉淀下来后面不管换什么检测任务都能直接复用这套检查流程。如果你在训练中发现标注里有漏网的错误框也欢迎告诉我我会在下一版里修正。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑