ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

yolov5测试数据集实战:检测图像中的人、猫和狗

yolov5测试数据集实战:检测图像中的人、猫和狗 简介YOLOv5测试数据集专为检测图像中的人、猫和狗设计面向目标检测算法学习者、模型训练者以及需要验证模型效果的开发者可有效解决训练完成后缺少标准测试数据、难以客观评估模型泛化能力的常见问题在项目开发与实验教学场景中尤为适用。压缩包内含501个文件由200张jpg测试图片、201个txt标注文件和100个xml标注文件共同组成其中txt采用YOLO格式适用于主流训练脚本xml采用Pascal VOC格式便于标注工具打开查看两种标注体系对照使用包体总计53.53MB且完整保留了所有原始图像信息解压即可直接投入实验。目前已有770人学习下载适合作为自行训练模型的验证集快速检验模型对人物、猫、狗等常见目标的识别效果同时也可用于数据格式转换练习、不同标注体系对比或围绕三类目标开展推理测试帮助使用者直观理解YOLOv5的预测输出、置信度阈值、mAP等关键评估指标从而提升实际调参与模型优化的效率。1. yolov5测试数据集的真实用途不训练也能验证检测能力很多人拿到“yolov5测试数据集-检测图像中的人、猫和狗”这个标题第一反应是“又要训练一个模型了”。但实际工作中测试数据集的最大价值不是训练而是验证——验证一个已经训练好的模型能不能在你自己的图片上认出人、猫、狗验证它的置信度阈值该设多少验证它在白天、黑夜、遮挡、小目标这些场景下翻不翻车。人、猫、狗恰好都是COCO数据集里的现成类别意味着你甚至不用自己训练直接拿官方yolov5权重就能跑推理测试数据集的角色就变成了“验收标准”。这篇笔记面向两类人一类是想快速验证yolov5部署效果、还没准备好训练数据的新手另一类是模型已经训练完、想系统评估检测精度和召回率的从业者。目标是用最少的代码把“给一堆图片检测人猫狗”这件事跑通并把踩过的坑一次说清楚。2. 准备测试数据三类目标的数据从哪来、按什么标准选2.1 现成数据集和自建测试集先搞清楚“测试”到底在测什么yolov5的测试数据集至少有两种截然不同的用法很多人一开始就混在一起。第一种是验证集——你在训练时留出来的那部分标注图片用来算mAP、Precision、Recall这类数据必须和训练集同分布标签格式得是yolov5的txt格式。第二种是推理测试集——随便找一堆日常图片不需要任何标注直接丢给模型推理看框得准不准、置信度是否合理。标题里“检测图像中的人、猫和狗”更偏向第二种属于模型部署前的冒烟测试。我一般会按三个标准来组织这类测试数据场景覆盖面、目标尺度分布、干扰项密度。场景至少包括室内、室外、单目标、多目标尺度上要故意放进去一些极小目标比如5米外的一条狗和极大目标占据画面大半的人干扰项包括猫狗玩偶、人形立牌、逆光、运动模糊。一套合格的人猫狗测试集大概准备30到50张图就够了多了徒增人工看框的成本少了覆盖不到边界情况。2.2 快速搭一个自己的测试集目录结构和文件命名规则如果你手头没有现成测试图片常见做法是从手机相册、公开图片站或公司历史项目里挑一批统一放到一个目录下。目录结构不用复杂yolov5的detect.py接受“目录”作为source参数会自动遍历里面所有图片。# 推荐目录结构 test_images/ ├── indoor/ │ ├── person_couch.jpg │ ├── cat_sofa.jpg │ └── dog_bed.jpg └── outdoor/ ├── person_street.jpg ├── cat_garden.jpg └── dog_park.jpg注意一个细节yolov5读取source时不会递归进入子目录它只读取根目录下的图片文件。所以如果你把图片分成了indoor和outdoor两个子目录要么分别用两次detect.py跑要么干脆全部平铺在一个目录里。文件命名建议用“目标_场景_序号”的格式这样后面看检测结果时一眼就能知道这张图期望出现什么目标人工核对效率高很多。2.3 验证集的标注转换从LabelImg到yolov5的txt格式如果你的测试集需要带标注用来算mAP那绕不开标注格式转换。yolov5的标签是txt文件每行一个目标格式是“类别id 归一化中心x 归一化中心y 归一化宽 归一化高”。LabelImg默认导出的是Pascal VOC的xml格式得转一手。# xml转yolov5 txt格式的核心逻辑 import xml.etree.ElementTree as ET import os def voc_xml_to_yolo(xml_path, out_dir, class_list): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) out_lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_list: continue cls_id class_list.index(name) box obj.find(bndbox) x1 float(box.find(xmin).text) y1 float(box.find(ymin).text) x2 float(box.find(xmax).text) y2 float(box.find(ymax).text) # 归一化中心点坐标 cx (x1 x2) / 2 / img_w cy (y1 y2) / 2 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h out_lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) with open(os.path.join(out_dir, os.path.basename(xml_path).replace(.xml, .txt)), w) as f: f.write(\n.join(out_lines)) class_list [person, cat, dog] # 类名必须与模型训练时一致这段代码的关键在于三个地方类别id必须严格对应模型训练时的class名排序对应错了检测框不会错但mAP统计全乱归一化坐标用的是整张图片的宽高不是某个区域xml里如果有被遮挡的难例目标yolov5训练时一般建议保留因为这也是数据分布的一部分。跑完转换后随机抽三五个txt文件人工看一眼坐标是否落在目标上这一步值得做因为坐标偏移是标注转换最常见的翻车点。3. 跑通最小推理一条命令验证人猫狗检测3.1 环境准备yolov5的依赖清单和版本选择在动手跑推理之前先把环境备好。yolov5官方仓库的requirements.txt里有一批固定依赖——torch、torchvision、opencv-python、numpy、pandas、matplotlib、seaborn、pyyaml、tqdm这些。常见做法是先建一个干净的conda环境避免和别的项目的包冲突。conda create -n yolo_test python3.9 -y conda activate yolo_test pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install -r requirements.txt依赖安装有两点容易踩坑。第一torch和torchvision必须在同一个源下装混用pip默认源和pytorch源容易装出CPU版torch跑起来慢得让人怀疑人生。第二requirements.txt里对numpy、opencv的版本有约束如果你的环境里已有其他项目锁定了numpy版本建议直接用conda新建环境不要在原有环境里硬装。3.2 最小推理命令用官方权重检测一批图片环境就绪后最直接的验证方式是直接用官方预训练权重跑推理。yolov5的detect.py自带下载权重的能力指定yolov5s.pt时如果本地没有它会自动从GitHub releases拉取。这里有个网络环境问题如果拉不动可以手动下载后放在yolov5仓库根目录下。python detect.py --weights yolov5s.pt --source ../test_images --conf-thres 0.25 --iou-thres 0.45 --project runs/test_result --name exp1 --exist-ok这条命令的含义--weights指定权重文件yolov5s是small版本速度最快精度够用--source指定测试图片目录--conf-thres是置信度阈值低于0.25的检测框会被丢弃--iou-thres是NMS的IoU阈值控制重叠框的合并力度--project和--name组合决定结果输出目录。跑完后在runs/test_result/exp1/下会生成同名图片每张图上画着检测框和置信度。新手第一次跑先看两件事框有没有稳定落在人、猫、狗身上以及置信度大致在什么区间。置信度普遍低于0.5说明权重和测试图片风格差异大或者conf-thres该往下调。3.3 用Python API替代命令行批量测试时更灵活detect.py适合一次性跑完看结果但如果要做批量测试、把结果写进日志或跟业务系统对接直接用Python API更顺手。yolov5的模型加载和推理接口很简洁。# 用yolov5 Python API做批量推理 import torch from pathlib import Path # 加载模型local表示使用本地权重不从网络下载 model torch.hub.load(ultralytics/yolov5, yolov5s, sourcelocal) # 批量推理传入图片目录 results model([../test_images/person_couch.jpg, ../test_images/cat_sofa.jpg, ../test_images/dog_park.jpg], size640) # 解析结果 for i, det in enumerate(results.pred): # det是tensor每行格式为[x1, y1, x2, y2, conf, cls_id] boxes det[:, :4].cpu().numpy() confs det[:, 4].cpu().numpy() cls_ids det[:, 5].cpu().numpy().astype(int) print(f图片{i}: 检测到{len(boxes)}个目标) for box, conf, cls_id in zip(boxes, confs, cls_ids): # 类别名映射取模型自带的names属性 cls_name model.names[cls_id] print(f {cls_name}: conf{conf:.2f}, box{box})这里的关键参数是size640它控制推理时输入网络的图像尺寸。yolov5s训练时默认就是640推理尺寸和训练尺寸一致检测效果最稳定。如果你测试的图片本身是1920x1080的大图yolov5内部会先缩放再推理框会映射回原图坐标所以不用担心输出的坐标是缩放后的。用Python API的好处是能直接在代码里拿到检测框坐标方便接着做业务逻辑——比如只保留“person”类、统计画面里猫狗数量、触发告警。坏处是torch.hub.load第一次执行可能尝试联网更新如果你在离线环境把sourcelocal换成直接加载本地权重文件更稳妥。4. 认识yolov5的检测参数conf-thres、iou-thres与max-det的调整4.1 置信度阈值决定“宁可漏报也不误报”还是反过来conf-thres是检测流程中第一个门槛。算法会对每个锚框输出一个“这个框里包含目标的概率”大于阈值的才进入后续处理。这个参数直接影响误报和漏报的平衡——阈值调高误报少但漏报增多阈值调低漏报少但会把背景识别成人。我用测试数据集调这个参数的方法是先用0.25跑一遍统计所有检测框的置信度分布然后把置信度在0.25到0.5之间的框单独拉出来看一遍。如果这批低置信度框里大部分是正确的检测说明测试集图片风格跟训练集差别大阈值可以降到0.15如果大部分是误报说明模型本身不够准调阈值解决不了根本问题得换大模型。这个分布的观察远比固定一个“最佳阈值”更可靠因为不同场景的最佳阈值可能完全不同——强光下猫的置信度普遍高逆光下狗的置信度可能只有0.2。4.2 IoU阈值与NMS为什么同一只猫会出两个框iou-thres控制的是NMS非极大值抑制阶段的行为。检测算法会对同一个目标产生多个重叠的候选框NMS负责把重叠度过高的候选框合并成一个。IoU阈值决定了什么算“重叠度过高”——阈值越低合并越激进越容易把挨得很近的两个目标合并成一个阈值越高保留的框越多容易对同一个目标输出两个重叠框。人猫狗检测里最常见的问题场景是一个人牵着一只狗人和狗在画面里高度重叠。此时如果IoU阈值设成0.6人和狗的框重叠区域很大NMS可能把狗框误判为人的重复框给合并掉。所以处理密集场景时我会把iou-thres从默认的0.45稍微提到0.5或0.55给高重叠目标留一点空间。代价是偶尔同一目标会出现重复框这个可以通过后处理再做一轮去重或者检查是否因为阈值太高导致了一个目标被两个候选框同时通过。4.3 max-det和图片尺寸小目标检测的两个隐蔽开关max-det限制了单张图片最多输出的检测框数量默认值是300日常测试很少碰它。但当一张图里有几十只狗、或者画面里目标极多时如果max-det过小后面的目标会被静默丢弃——这是最隐蔽的漏检原因因为它没有任何报错只是少给了几个框。图片尺寸size/inference-size是另一个容易被忽略的参数。如果测试集里有很多小目标比如远处的一只猫只占图像的5%640的推理尺寸可能太小小目标的特征在缩放过程中被压没了。我一般会把推理尺寸提到960或1280再跑一遍对比检测结果。这不是培训魔改而是检测流程里的标准调优手段——更大的输入尺寸保留更多小目标细节。代价是推理耗时至少翻倍这就要看你是离线测试还是线上实时了。参数默认值场景调整建议过大过小conf-thres0.25高精度场景0.4高召回场景0.1漏检多误报多iou-thres0.45密集重叠场景0.5~0.6重复框漏掉重叠目标max-det300超大场面调大内存占用高静默丢目标size640小目标加码到960/1280推理慢小目标漏检这套参数调完以后一定要把同一批测试图过一遍并保存结果对比不同参数下的框效果肉眼确认“调参收益”是真实可见的而不是凭感觉设置。调参这事本质上就是给模型适配你的特定测试集几个参数的组合效果要看整体表现不能孤立的只调单个值。唯一能确信的是结果要落在你手上的这批图上看起来更贴近你对目标检测的需求。5. 常见坑与排查标注格式、环境依赖、识别错漏5.1 标注错位、类别对应错乱与文件路径中的空格是绕不开的坑最典型的翻车现场是检测结果文件生成成功、框的位置也对但“狗”显示成了“猫”或者所有类别的名字都差了一个序号。仔细查一下才会发现其实是标注文件和模型输出用的不是同一套类别列表或者txt文件名和图片名对不上。标注错位和类别对应错乱这两个问题往往同时出现——xml转txt时类名索引取错或者txt文件命名和图片不匹配数据加载时张冠李戴。排查方式是随机抽取五个txt文件逐个检查类别id对应的类名是否一致再确认txt文件名不含扩展名和图片文件名完全一致。文件路径里的中文和空格也会在detect.py读取时出问题——不是一定会挂但一旦路径解析不对报错信息又晦涩难懂排查成本极高。我习惯把测试集路径统一改成英文、无空格的目录从源头消灭这个隐患。5.2 模型检测不到任何目标先看图再看参数最后看权重推理跑完输出图片上一片空白一个框都没有。这种情形的排查路径是固定的。第一步打开原图确认图上目标是不是真的可见——如果人都背对着镜头且只有拇指大那模型漏检是正常的。第二步检查运行日志里有没有正常的检测过程输出确认不是代码报错静默中断。第三步把conf-thres调低到0.1再跑一次如果还是没有框问题基本不在阈值而是权重和测试图片完全不匹配。这里有个我自己踩过的坑拿yolov5s官方权重去测一张专门的“猫狗表情包”图片上面是两只特别卡通化的猫结果一个框都出不来。原因是官方权重在COCO数据集上训练COCO里有真实猫狗照片但卡通猫和真实猫的视觉特征差异太大模型给出的置信度极低。这不算模型坏了是数据和训练分布差异太大。解决办法是换真实照片测试或者用你自己的数据训练一个适配模型。5.3 检测到目标但类别弄反了人猫狗的语义边界问题另一种常见情况是框的位置是对的但“人”被识别成“猫”“狗”被识别成“人”。这通常有两类原因。一是视觉相似性——远处一个人的轮廓和一只蹲着的狗从特征上看确实有重叠二是上下文缺失——模型只看到局部特征如果图片里一个人抱着一只猫猫的框可能部分覆盖了人的躯干导致分类置信度分布被拉偏。排查方法是看模型对每个候选框输出的完整类别置信度分布。yolov5在NMS之前有所有类别的得分但detect.py只输出最高分对应的类别。想看到置信度分布得用Python API拿det的原始输出或者自己调一下模型的前向代码。如果“人”和“狗”两个类别的置信度非常接近比如0.4对0.38说明模型对这张图本身就模棱两可不是bug而是训练数据里这两个类别在该场景下的区分度不够。这个现象在COCO数据集上其实不算罕见——COCO的person类里有大量站立或走路的行人而dog类里有很多走动的狗两者的边缘轮廓在某些角度下确实会近似。5.4 显存不足导致推理中断batch-size和torch线程的取舍最后这个问题专门坑那些用游戏本或本地工作站跑测试的人——显存报错CUDA out of memory。人的本能是把batch-size调到1但可能还是爆显存。看一眼错误信息就会发现问题经常不在batch而在于输入尺寸和模型本身比如——推理尺寸960x960加上yolov5x权重单张输入就可能吃掉好几GB显存。先把size改回640再把batch-size设为1跑一次基本就能解决。python detect.py --weights yolov5s.pt --source ../test_images \ --batch-size 1 --size 640 --device 0如果显存还是不够加一行推理前清空缓存并把torch的后台线程数设置降下来。torch会默认开启所有CPU核心参与数据加载这个行为很吃内存。# 推理脚本里加载模型之前设置 import torch torch.set_num_threads(2) # 限制CPU线程减少内存压力 torch.cuda.empty_cache() # 清空显存缓存6. 用测试结果验证模型边界类别混淆、小目标和漏检的检查习惯当一批测试图的检测结果跑完别急着下结论说“模型能检测人猫狗了”。一份可靠的测试报告至少应该包含三个维度的统计单类别精确率检出的框里有多少确实是对应目标、单类别召回率目标有多少被漏掉了以及误报类别分布哪些东西被错认成了人猫狗。如果你没有标注数据精确率可以人工数出来召回率只能靠估——但至少你可以记录“哪些图上哪些目标没被检出”总结漏检目标共有的特征。我建议把每张测试图的检测结果类别、置信度、框坐标导出一份JSON再写个小脚本统计分布。这一步看起来繁琐但对后续模型选型价值很大。比如你发现所有“狗”的检测置信度都在0.2以下而“人”都在0.6以上说明狗这个类别在你的测试分布下表现偏弱要么换yolov5m权重看有没有改善要么针对狗的场景补充训练数据。举个例子——我之前测过一批宠物店图片模型把店里的猫爬架当成猫的概率高得离谱这就是典型的上下文误报在报告里专门标出来后续做业务时加一条规则“置信度低于0.3的cat检测不生效”比重新训练模型快得多。这个检查习惯一定要养成。我现在的固定流程是每批测试图跑完先看置信度分布直方图再挑出置信度最高的十个误报和最低的十个漏检确认它们的共性。如果共性明显比如全部是暗光、全部是密集重叠、全部是某个特定角度就把这类图并入下一轮测试集。测试集不是一次性建完就固定不变它会随着模型迭代和业务场景变化持续扩充——这比反复调参数更值得投入时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表