news 2026/10/10 18:59:48

YOLO猫狗目标检测数据集:1000张图+三种标签格式+划分脚本+训练教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLO猫狗目标检测数据集:1000张图+三种标签格式+划分脚本+训练教程

简介:这份资源面向目标检测初学者与需要快速搭建猫狗识别任务的开发者,提供一套真实场景下的YOLO猫狗目标检测数据集。图片均经labelimg精细标注,标注框质量较高,并同步给出voc(xml)、coco(json)与yolo(txt)三种格式标签,分别存放于不同文件夹,可直接接入YOLO系列模型训练,省去格式转换的繁琐步骤。压缩包共2000个文件,以1000个xml标注文件和990个txt标签文件为主,另含少量html教程、py划分脚本与yaml配置文件,整体约23.05MB,体积轻便易于下载与迁移。资源还附赠数据集划分脚本,可按需生成训练集、验证集与测试集,并配套Windows与Linux环境搭建及训练案例教程,帮助读者从环境配置到模型训练完整走通流程。目前已有1357人学习下载,适合作为课程设计、毕业设计或入门练手的实战数据。

1. 从一份猫狗数据集说起:1000 张图、三套标签、一个划分脚本到底能省多少事

如果你正在入门 YOLO 目标检测,大概率卡在同一个地方:模型结构看懂了,损失函数也背下来了,但一打开标注工具就懵了——标完几十张图,导出格式选错,训练脚本读不进去,改完格式又发现训练集和验证集混在一起,指标虚高得离谱。这份「YOLO 猫狗目标检测数据集(含 1000 张图片)+ 对应 VOC、COCO 和 YOLO 三种格式标签 + 划分脚本 + 训练教程」正好打在这个痛点上。它把数据准备阶段最容易翻车的三件事——标注格式转换、数据集划分、训练配置——打包成一条可复现的流水线。猫狗二分类检测虽然简单,但它是验证整套流程是否跑通的最佳试验场:类别少、目标大、标注歧义低,跑不通基本就是流程问题而不是数据问题。适合刚接触 YOLO 数据集的新手,也适合想把手头杂乱标注统一成标准格式的熟手。

2. 三种标签格式到底差在哪:VOC、COCO、YOLO 的坐标逻辑与选型

2.1 坐标表示与目录结构的本质区别

很多人以为三种格式只是文件后缀不同,实际上它们的坐标基准和目录组织完全不一样。VOC 用 XML,坐标是绝对像素值,左上角和右下角两个点确定一个框;COCO 用单个 JSON,坐标是[x, y, width, height]的绝对像素,且所有图片的标注集中在一个文件里;YOLO 用每张图对应的.txt,坐标是归一化后的[x_center, y_center, width, height],值域 0 到 1。

这个差异直接决定了你在训练时要不要改代码。YOLO 官方训练脚本默认读 YOLO 格式,如果你手里只有 VOC 的 XML,就必须先转。而 COCO 格式因为标注集中,适合做数据集的统计分析,比如统计每个类别的框数量分布,但不适合直接喂给 YOLO 训练。

格式标注文件坐标类型坐标含义类别存储
VOC每图一个 XML绝对像素xmin, ymin, xmax, ymaxXML 内 name 字段
COCO单个 JSON绝对像素x, y, width, heightJSON 内 categories 数组
YOLO每图一个 TXT归一化x_center, y_center, width, heightTXT 行首 class_id

选型建议很直接:训练用 YOLO 格式,做数据分析或跨框架迁移时保留 COCO,VOC 作为中间交换格式。这份数据集同时提供三种,意味着你可以跳过自己写转换脚本的环节,但理解转换逻辑仍然必要,因为实际项目中你拿到的往往是单一格式。

2.2 从 VOC 转 YOLO 的最小转换脚本

假设你拿到的是 VOC 格式的 XML,想转成 YOLO 的 TXT,核心就是读 XML、取尺寸、算归一化坐标。下面这段脚本可以直接抄:

import xml.etree.ElementTree as ET import os # 类别映射,猫狗数据集只有两类 class_map = {"cat": 0, "dog": 1} def voc_to_yolo(xml_path, output_dir, img_w, img_h): tree = ET.parse(xml_path) root = tree.getroot() # 用图片实际尺寸做归一化基准,不能硬编码 size = root.find("size") w = int(size.find("width").text) h = int(size.find("height").text) lines = [] for obj in root.findall("object"): cls_name = obj.find("name").text if cls_name not in class_map: continue cls_id = class_map[cls_name] bbox = obj.find("bndbox") xmin = float(bbox.find("xmin").text) ymin = float(bbox.find("ymin").text) xmax = float(bbox.find("xmax").text) ymax = float(bbox.find("ymax").text) # 归一化并转为中心点加宽高 x_center = (xmin + xmax) / 2.0 / w y_center = (ymin + ymax) / 2.0 / h bw = (xmax - xmin) / w bh = (ymax - ymin) / h lines.append(f"{cls_id} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}") # 输出文件名与图片名一致,只是后缀换成 txt base = os.path.splitext(os.path.basename(xml_path))[0] with open(os.path.join(output_dir, base + ".txt"), "w") as f: f.write("\n".join(lines))

逻辑说明:先解析 XML 拿到图片宽高,注意这里必须用 XML 里记录的尺寸,不能假设所有图片都是 640×640。然后遍历每个 object,取类别名映射到数字 id,取边界框坐标做归一化。归一化时中心点除以宽高,宽高也除以宽高,得到 0 到 1 之间的小数。最后写入 TXT,每行一个目标,空格分隔。

参数说明:class_map必须和你的data.yaml里的names顺序一致,否则训练时类别会错位。img_w和img_h虽然传进来了,但实际用的是 XML 里的尺寸,这样更安全。输出目录要提前建好,脚本不会自动创建。

2.3 COCO 格式的读取与类别统计

COCO 的 JSON 结构适合做统计分析。比如你想知道猫和狗各有多少个标注框,用下面几行就能跑出来:

import json from collections import Counter with open("annotations/instances.json", "r") as f: coco = json.load(f) # 建立 category_id 到名字的映射 cat_id_to_name = {c["id"]: c["name"] for c in coco["categories"]} counter = Counter() for ann in coco["annotations"]: counter[cat_id_to_name[ann["category_id"]]] += 1 print(counter) # 输出类似 Counter({'cat': 620, 'dog': 580})

这段代码不涉及训练,但能帮你判断数据集是否类别不平衡。如果猫狗数量差距超过 3 比 1,训练时就要考虑加类别权重或者做重采样。COCO 的annotations数组里每个元素包含image_id、category_id、bbox,bbox是[x, y, width, height]绝对像素。注意 COCO 的id从 1 开始,而 YOLO 的 class_id 从 0 开始,转换时要减一。

3. 划分脚本怎么写才不翻车:训练集、验证集、测试集的比例与随机种子

3.1 为什么不能直接随机切分文件

很多人划分数据集就是random.shuffle然后按比例切,但这样有一个隐蔽问题:如果同一个场景的图片被切到训练集和验证集,验证指标会虚高。猫狗数据集里如果有多张同一只猫在不同角度的照片,随机切分会让模型在验证集上「见过」这只猫,指标好看但实际泛化能力差。

更稳妥的做法是按图片内容分组再切分,但这份数据集没有提供分组信息,所以退而求其次:固定随机种子,保证每次划分结果一致,至少让实验可复现。下面这个脚本同时处理图片和对应的 YOLO 标签文件:

import os import random import shutil def split_dataset(img_dir, label_dir, output_dir, ratios=(0.7, 0.2, 0.1), seed=42): random.seed(seed) # 固定种子,保证可复现 images = [f for f in os.listdir(img_dir) if f.endswith((".jpg", ".png"))] random.shuffle(images) n = len(images) n_train = int(n * ratios[0]) n_val = int(n * ratios[1]) splits = { "train": images[:n_train], "val": images[n_train:n_train + n_val], "test": images[n_train + n_val:] } for split, files in splits.items(): img_out = os.path.join(output_dir, split, "images") lbl_out = os.path.join(output_dir, split, "labels") os.makedirs(img_out, exist_ok=True) os.makedirs(lbl_out, exist_ok=True) for img_file in files: # 复制图片 shutil.copy(os.path.join(img_dir, img_file), os.path.join(img_out, img_file)) # 复制同名标签,后缀换成 txt base = os.path.splitext(img_file)[0] label_file = base + ".txt" src_label = os.path.join(label_dir, label_file) if os.path.exists(src_label): shutil.copy(src_label, os.path.join(lbl_out, label_file)) else: # 没有标签的图片通常是负样本,创建空文件 open(os.path.join(lbl_out, label_file), "w").close() print(f"train: {len(splits['train'])}, val: {len(splits['val'])}, test: {len(splits['test'])}")

逻辑说明:先固定随机种子,保证每次运行划分结果一样。然后打乱图片列表,按 7:2:1 切分。复制时图片和标签必须同名,标签文件如果不存在就创建空文件,因为 YOLO 训练时负样本也需要对应的空 txt,否则会报错找不到标签。

参数说明:ratios三个数之和必须为 1,常见做法是 7:2:1 或 8:1:1。数据量只有 1000 张时,测试集 100 张足够评估,验证集 200 张用于调参。seed建议固定,否则每次划分不同,实验无法对比。

3.2 划分后的目录结构检查

划分完成后,目录应该长这样:

dataset/ ├── train/ │ ├── images/ (700 张) │ └── labels/ (700 个 txt) ├── val/ │ ├── images/ (200 张) │ └── labels/ (200 个 txt) └── test/ ├── images/ (100 张) └── labels/ (100 个 txt)

检查两个点:图片数量和标签数量是否一致,以及每个标签文件的行数是否和图片里的目标数匹配。可以用一行命令快速统计:

# 统计 train 下所有 txt 的总行数,即总标注框数 find dataset/train/labels -name "*.txt" -exec cat {} + | wc -l

如果这个数字远小于图片数,说明很多图片没有标注,可能是漏标或者负样本。猫狗数据集里每张图至少有一只猫或狗,所以总框数应该接近 1000 到 1500 之间。

3.3 data.yaml 的写法与路径陷阱

YOLO 训练需要一个data.yaml告诉它数据在哪、类别是什么。写法如下:

path: /home/user/dataset # 数据集根目录,绝对路径 train: train/images val: val/images test: test/images names: 0: cat 1: dog

注意path必须是绝对路径,train和val是相对于path的子路径。很多人在这里翻车:写了相对路径,训练时找不到图片,报No such file or directory。另一个坑是names的顺序必须和转换脚本里的class_map一致,否则猫被识别成狗。

4. 训练教程里的关键参数:从 yolov8n.pt 到收敛的完整命令

4.1 环境安装与最小训练命令

假设你用 PyCharm 或者命令行,先装 ultralytics 包:

pip install ultralytics

然后一行命令启动训练:

yolo detect train data=dataset/data.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16

这条命令的含义:用yolov8n.pt预训练权重,在data.yaml指定的数据集上训练 100 轮,输入尺寸 640,批次大小 16。yolov8n是最小的模型,参数量少,适合 1000 张图的小数据集,不容易过拟合。

参数怎么改:如果显存不够,把batch降到 8 或 4;如果训练损失下降很慢,把epochs加到 200;如果图片里目标很小,把imgsz提到 1280,但显存占用会翻倍。猫狗目标通常占图片面积较大,640 足够。

4.2 训练过程中的指标解读

训练开始后,控制台会输出每一轮的损失和指标。重点看三个:

  • box_loss:边界框回归损失,应该持续下降,如果震荡说明学习率太大。
  • cls_loss:分类损失,猫狗二分类应该很快降到 0.1 以下。
  • mAP50:IoU 阈值 0.5 时的平均精度,这是最终指标,猫狗数据集上通常能到 0.9 以上。

如果mAP50在 0.5 左右就上不去,检查标签格式是否正确。常见问题是归一化坐标算错了,比如把绝对坐标直接写进 txt,导致框全部跑到图片外面。

4.3 用训练好的模型做推理

训练完成后,权重保存在runs/detect/train/weights/best.pt。推理命令:

yolo detect predict model=runs/detect/train/weights/best.pt source=test_images/ save=True

source可以是单张图片、文件夹或视频。save=True会把画了框的结果保存到runs/detect/predict/。如果想看置信度,加conf=0.5只显示置信度大于 0.5 的框。

推理时如果发现框的位置偏移,大概率是训练时的imgsz和推理时不一致。YOLO 会自动缩放,但缩放比例算错就会偏。保持训练和推理的imgsz一致最稳妥。

5. 避坑与排查:猫狗数据集训练中最容易翻车的 4 个地方

5.1 现象:训练报错Label class 2 is not in the dataset

原因:标签文件里的 class_id 超出了data.yaml里names的范围。猫狗只有 0 和 1,如果出现 2,说明转换脚本的class_map写错了,或者 VOC 的 XML 里有其他类别没过滤掉。

解决:检查所有 txt 文件里的第一个数字,用awk '{print $1}' *.txt | sort -u看有哪些值。如果有 2,回到转换脚本,在if cls_name not in class_map: continue那里确保只保留猫狗。

5.2 现象:训练损失正常下降,但 mAP 一直是 0

原因:标签文件的坐标归一化算错了,比如用了绝对坐标除以 255 而不是除以图片宽高。或者图片和标签文件名不匹配,YOLO 读不到标签,把所有图片当负样本训练。

解决:随机抽一个 txt 文件,看里面的数值是否在 0 到 1 之间。如果大于 1,说明归一化错了。再检查图片名和标签名是否只差后缀,比如cat_001.jpg对应cat_001.txt。

5.3 现象:验证集指标比训练集还高

原因:数据集划分时没有固定随机种子,或者验证集图片和训练集图片有重复。1000 张图里如果有同一张图的不同副本,随机切分可能把它们分到不同集合。

解决:用md5sum对所有图片去重,确保没有重复文件。划分脚本里固定seed,并且每次实验用同一个划分结果。

5.4 现象:推理时框的位置整体偏移

原因:训练时用了imgsz=640,推理时图片被缩放到其他尺寸,但 YOLO 的坐标还原逻辑依赖训练时的尺寸。如果推理时手动改了imgsz,坐标会偏。

解决:推理命令里显式指定imgsz=640,和训练保持一致。如果必须用其他尺寸,重新训练时就用那个尺寸。

6. 把 1000 张图用到极致:数据增强与难例挖掘的两个技巧

1000 张图在目标检测里算小数据集,直接训练容易过拟合。除了 YOLO 自带的 mosaic、翻转、缩放增强,还有两个技巧能明显提升泛化能力。

第一个是「复制粘贴增强」。猫狗数据集里如果某些姿态的样本少,可以把猫或狗的目标框裁剪出来,随机粘贴到其他图片的背景上,生成新的训练样本。ultralytics 支持通过copy_paste参数开启,但需要分割掩码。没有掩码时,可以用矩形框裁剪加高斯模糊边缘,减少粘贴痕迹。这个技巧在猫狗这种目标边界清晰的场景下效果很好,能把有效样本量翻倍。

第二个是「难例挖掘」。训练完第一轮后,用best.pt在验证集上推理,把置信度低于 0.5 但实际有目标的图片挑出来,人工检查标注是否正确。常见问题是猫狗重叠时只标了一只,或者夜间照片里目标太暗漏标。把这些难例修正后加入训练集,再跑第二轮,mAP 通常能涨 2 到 5 个点。

我自己的习惯是:第一轮训练只跑 50 轮,拿到best.pt后先看验证集上的错误案例,把漏标和错标修完再跑完整 100 轮。这样比直接跑 200 轮省时间,而且最终指标更高。数据集的质量永远比数量重要,1000 张标对的图比 5000 张标错的图有用得多。希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 18:59:01

数据结构与算法刷题攻略:两遍学习法与复习重写实战

简介:一份面向程序员求职与算法进阶的刷题全攻略资料包,整合剑指Offer题解、程序员代码面试指南题解、九章算法讲解、牛客直通BAT算法课等经典内容,同时收纳大公司笔试真题与LintCode编程题练习,基本覆盖算法面试常见题型与解题思…

作者头像 李华
网站建设 2026/10/10 18:57:12

Pytest+Allure+Excel搭建接口自动化测试框架实践

做接口测试这些年,我一直坚持一个朴素的判断:一个接口自动化测试框架能跑起来不算本事,能在团队里被“用起来”才算本事。今天要聊的这套接口自动化测试框架,主技术栈就是 Pytest Allure Excel,三者各司其职&#xf…

作者头像 李华
网站建设 2026/10/10 18:56:37

塞曼效应三种理论解释:经典、旧量子论与新量子力学的范式演进

简介:本资源是一份面向物理学专业本科生及研究生的理论物理学习资料,聚焦塞曼效应这一核心量子现象,系统对比经典理论、量子力学与相对论三种解释路径的物理图像、数学推导逻辑与适用边界。资料以PDF形式呈现,全文1.31MB&#xff…

作者头像 李华
网站建设 2026/10/10 18:52:28

装甲板表面缺陷检测:高反光小目标YOLOv8实战指南

简介:本资源是面向机器人视觉开发与智能装备识别领域的实战型目标检测数据集,专为YOLO系列模型训练优化,解决机器人对抗赛中装甲板多编号、多颜色小目标的精准识别难题。数据集共1125张真实对抗场景图片(含训练/验证/测试集&#…

作者头像 李华
网站建设 2026/10/10 18:49:14

NumPy为何比Python列表快?ndarray原理与实战解析

我当年第一次用纯Python处理一份五十万行的交易数据,一个双层for循环跑完用了将近三分钟,换NumPy重写之后,同样的计算量压缩到零点几秒。那个差距不是Python这个语言"不行",而是标准列表从一开始就没打算帮你做重数值运…

作者头像 李华