资讯详情

YOLO猴子检测实战:4690张图像数据集从校验到训练微调

📅 2026/10/11 23:02:42 | 华诺云谱 👁 阅读
YOLO猴子检测实战:4690张图像数据集从校验到训练微调
简介这是一份面向目标检测开发者的猴子检测数据集适用于YOLO系列算法可直接用于模型训练、验证与测试。数据已预先划分训练、验证、测试集并附带data.yaml配置文件适配YOLOv5、YOLOv7、YOLOv8、YOLOv9、YOLOv10、YOLO11等主流版本。标签同时提供YOLO格式txt与VOC格式xml两种分别保存在独立文件夹YOLO格式中每条记录依次为目标类别索引、归一化中心点横纵坐标及宽高VOC格式则采用标准XML标签结构坐标均按图像尺寸归一化便于无缝切换训练框架。压缩包共2000个文件以XML标签文件为主整体约240.16MB配合配置文件即可直接训练和验证。对需要猴类检测样本的初学者和算法研究人员而言这套数据省去数据采集与手工标注环节下载后调整路径即可开展实验。当前已有84人学习使用是实践YOLO系列目标检测任务的轻量实用数据集。1. 猴子检测数据集在YOLO落地里的位置不是拿来就训而是先盘数据做野生动物监测的同事上周找我说景区猴子抢包投诉不断想上一套自动识别告警。这类需求在目标检测项目里很常见但很多人开局就卡在数据上yolo算法本身跑通不难难的是有一批带标注、能直接喂进训练脚本的图像。标题里这个猴子检测数据集4690张图像带标签打包成一个zip解决的正是从零起步时最耗时的一环。这个数据集适合三类人刚接触目标检测、想用现成数据把YOLO训练-验证-部署整条链路走通的新手做灵长类行为分析、生态监测的研究者在景区、农场、实验动物房做入侵检测的工程人员。4690张对单类目标检测来说是中等偏小的规模能训练出可用模型但距离生产级精度还有距离后面需要通过微调和难例挖掘去补。需要先说明的是打开压缩包之前不要默认里面的标注格式就是你想的YOLO txt。常见做法是解压后先盘一盘点数再决定要不要写转换脚本。这一步省掉后面训练翻车时再回头看浪费的就不只是半小时。2. 拿到zip后的第一件事解压、目录结构与数据校验2.1 解压与目录结构先看清images和labels怎么排很多数据集打包时会顺手把原始文件名、标注文件混在一起甚至把标注工具生成的coco json、VOC xml一起塞进来。如果直接训练YOLO训练脚本找不到对应标注报错一堆这就是最常见的翻车点。我一般会先把zip解压到一个干净目录再用tree或find把层级打出来确认到底有没有images和labels两个兄弟目录以及标签文件是txt还是xml。unzip yolo算法-猴子检测数据集-4690张图像带标签-.zip -d monkey_dataset find monkey_dataset -type d | head -20 find monkey_dataset -type f -name *.xml | wc -l find monkey_dataset -type f -name *.txt | wc -l第一行解压时不覆盖同名文件-d monkey_dataset指定目标目录避免解压到当前路径把文件散得到处都是。后面三行分别看目录层级、xml和txt数量如果txt数量接近4690大概率就是YOLO原生格式如果xml有几千个而txt没有说明是VOC标注要先转换再训练。这一步能省掉后续许多无效调试。解压后常见目录结构有两种。一种是images/和labels/平级图片在images里同名txt在labels里这是YOLO最熟悉的结构另一种是train/valid/下各带images/和labels/属于已经按数据集划分好的结构和coco2017数据集结构的思想一致。无论哪种关键准则只有一个图片文件名和标签文件名必须一一对应比如IMG_001.jpg对应IMG_001.txt。如果打开发现是VOC的xml也别慌。常见做法是写一个几十行的转换脚本把xml里的object标签解析出来按class x_center y_center width height的归一化格式写入txt。注意边界框坐标是左上角和右下角要自己转成中心点宽高同时除以图片宽高做归一化否则YOLO会把它当像素值读训练结果惨不忍睹。2.2 数据校验别只数文件要写脚本查对应关系文件数量对得上不代表标签能直接用。zip传输、解压工具差异、标注工具导出时漏写都会让图片和标签错位。我见过一次实际案例解压后图片4690张、标签4690个但其中几十个txt内容是空的训练时这几十张图被跳过mAP没受影响但recall上不去。空文件、多类别、类别索引越界这些问题靠眼睛看不出来必须写脚本批量校验。import os from pathlib import Path root Path(monkey_dataset) img_dir root / images # 图片目录 lab_dir root / labels # 标签目录 imgs sorted(img_dir.glob(*.jpg)) sorted(img_dir.glob(*.jpeg)) sorted(img_dir.glob(*.png)) labs sorted(lab_dir.glob(*.txt)) print(图片数:, len(imgs), 标签数:, len(labs)) # 1. 检查同名对应 img_names {p.stem for p in imgs} lab_names {p.stem for p in labs} only_img img_names - lab_names only_lab lab_names - img_names print(缺标签的图片:, len(only_img), 缺图片的标签:, len(only_lab)) # 2. 遍历标签统计类别索引和空文件 from collections import Counter cls_counter Counter() empty_files [] for lab_file in labs: lines [l.strip() for l in lab_file.read_text().splitlines() if l.strip()] if not lines: empty_files.append(lab_file.name) continue for line in lines: cls_counter[int(line.split()[0])] 1 print(类别索引分布:, dict(cls_counter)) print(空标签文件数:, len(empty_files))这段脚本做两件事第一用文件主名集合做差集把缺标签或缺图片的文件名找出来第二读取每个txt统计每行第一个数字的类别分布。空标签文件能直接被发现类别索引是否连续、有没有出现异常类别也一眼能看出来。参数上只需要改root指向你的解压目录如果图片后缀不是常见的三种在glob里补上即可。校验时最该警惕的是标签内容里出现两张以上图片共用一个txt或者txt行数和图片数对不上。还有一种隐蔽情况标注用了多类别但压缩包只给了一个类别此时cls_counter会告诉你真实类别数后续写data.yaml的names列表时要用它而不是用下载页面写的。提示如果图片数和标签数不一致先看差集文件再决定是补标还是删图。许多人这里偷懒直接训练结果训练日志里样本数莫名变少找半天才发现是空标签拖了后腿。盘完数据就该进入训练环节。这里的关键不是把命令跑起来而是把数据配置和模型选型想清楚否则一顿操作后得到的模型基本没法用。3. 用YOLOv8把猴子检测跑通从data.yaml到训练参数3.1 写data.yaml并划分训练验证集别用随机洗牌ultralytics框架在训练前要找一份data.yaml里面指定训练验证图片路径和类别名。我一般会先按8:2划分train和valid两个目录再写yaml。划分这一步有个讲究不要用随机洗牌后直接切尤其当zip包里图片是按时间连续采集时随机切会让同一镜头下的相似猴子同时出现在训练集和验证集看着精度高去了新场景就翻车。按文件名哈希或按拍摄时间点划分更稳妥。import hashlib, shutil from pathlib import Path root Path(monkey_dataset) img_dir root / images lab_dir root / labels for part in [train, valid]: (root / part / images).mkdir(parentsTrue, exist_okTrue) (root / part / labels).mkdir(parentsTrue, exist_okTrue) for img_path in list(img_dir.glob(*.jpg)) list(img_dir.glob(*.jpeg)) list(img_dir.glob(*.png)): h hashlib.md5(img_path.stem.encode()).hexdigest() part train if int(h, 16) % 10 8 else valid lab_path lab_dir / (img_path.stem .txt) assert lab_path.exists(), f标签缺失: {img_path} shutil.copy(img_path, root / part / images / img_path.name) shutil.copy(lab_path, root / part / labels / lab_path.name)划分依据是图片文件名的md5值取模同一个名字永远落到同一个集合稳定、可复现也避免了相邻时序的图片挤进同一侧。assert会在标签缺失时立刻中断比后续训练报错更直观。如果你希望显式控制随机性可以把hashlib.md5(...).hexdigest()换成random.seed(42)加random.random()但文件名哈希的好处是不依赖执行顺序重跑结果不变。然后写data.yaml内容如下path: /absolute/path/to/monkey_dataset # 数据集根目录建议写绝对路径 train: train/images val: valid/images nc: 1 names: [monkey]path写绝对路径可以避免相对路径在不同目录下启动训练时找不到图片nc和names必须和2.2校验脚本里统计的类别索引对上。如果压缩包是猴子人两类这里就要改成nc: 2, names: [monkey, person]否则训练时类别索引1会被当成越界轻则警告重则模型把人和猴子混在一起。注意data.yaml里train和val写的是相对path的路径不是系统绝对路径。这一点经常有人写反导致训练报No labels found in ...其实是路径拼错。3.2 训练命令与参数imgsz、batch、epoch怎么选写好了数据配置训练命令本身不复杂。常见的做法是直接用ultralytics的Python API或CLI。我习惯在命令行里先跑一个小epoch数验证流程再上完整训练避免一上来就大训练然后发现数据路径配错。yolo detect train \ modelyolov8n.pt \ datamonkey_dataset/data.yaml \ imgsz640 \ batch16 \ epochs10 \ device0 \ cacheTrue先用yolov8n.pt预训练权重做10轮确认损失下降、验证集有输出。imgsz640是YOLOv8默认推理尺寸对猴子检测够用batch16取决于显卡显存12GB显存用16没问题6GB建议降到8cacheTrue把图像缓存进内存第一次慢之后每一轮会快很多缺点是占内存。10轮跑完看results.png里的混淆矩阵和验证曲线确认没有类别丢失后再调大epoch正式训练。正式训练时我一般会把epochs放到100到150轮开启早停。patience是早停的轮数比如在命令行加patience20告诉框架如果连续20轮验证集mAP没有提升就停能省不少时间。还有一个参数rectTrue可以加速训练它不再强制把所有图resize成同样的正方形而是按长宽比分组适合解压包里图片尺寸不一的场景缺点是batch内分布差异大时收敛略慢。另外如果显存确实紧张优先降batch而不是降imgsz。猴子是中小目标降到imgsz416后小猴子的特征明显变弱召回掉得厉害。batch从16降到8训练时间多一倍但精度几乎不变却能把OOM解决掉。yolo detect train \ modelyolov8s.pt \ datamonkey_dataset/data.yaml \ imgsz640 \ batch8 \ epochs120 \ device0 \ cacheTrue \ patience20 \ projectruns_monkey \ nameexp_full这里换成yolov8s.pt是因为4690张图用nano也能训但s模型对复杂背景下的猴子特征拟合更好代价是显存和推理时间都变高。project和name用来指定输出目录方便后续多组实验对比。训练结束后最常看的文件是runs_monkey/exp_full/weights/best.pt这是验证集表现最好的权重后续不管是验证还是部署都用它而不是用最后一轮权重。训练日志里会有很多数字但真正要盯的是val/box_loss和val/cls_loss是否在下降后稳定以及每个epoch结束时的mAP50。如果mAP50始终在0.2以下先别急着加数据集按下一章的清单排查。模型训练不是按下按钮就结束。数据集本身的质量、划分方式、标签一致性都会在训练结果里放大。下面这些都是我在几个项目里真实遇到过的坑。4. 猴子检测训练常见的5个坑从翻车现场倒推参数4.1 训练的类别数对不上mAP却显示为0现象训练日志正常验证时mAP50始终为0confusion_matrix.png里所有预测都被分到背景类。原因data.yaml里nc写的是1但标签txt里除了0还有1或者反过来标签txt里只有0nc却写成2。YOLO读取标签时不会因为类别越界直接崩溃而是把越界的样本当作背景或直接跳过结果就是模型学了个寂寞。解决回到第2.2节那个统计脚本把每个txt里出现过的类别索引全部列出来确认data.yaml的names长度和最大索引1完全相等。我还会在训练前打印data.yaml读取后的train和val里nc用两行代码再次确认而不是相信下载页面写的标注类别数。这个坑在单类数据集上最容易踩因为下载页面写“猴子检测”就顺手写了nc: 1没有意识到zip里还混着其他类别。4.2 图片尺寸参差不齐训练到一半CUDA OOM现象batch16时前几个epoch正常跑了一段时间后显存溢出报CUDA out of memory。原因数据集里混着几张超大分辨率图片比如4000x3000的监控截图YOLO在letterbox时会先缩放再填充但超大图在数据增强阶段占用显存远大于常规图峰值瞬间爆掉。这类图往往来自不同来源拼接解压后只看文件名看不出异常。解决训练前批量检查图片尺寸把边长超阈值的先压缩或裁切。常见做法是在校验脚本里加上PIL.Image.size判断把超过2000px的图统一压到1600px以内。另外把batch降到8并给cacheTrue换成cacheram或disk也能减少峰值。不要因为一次OOM就盲目把imgsz降到320小目标检测的代价太大。4.3 随机划分数据集验证集和训练集分布失衡现象训练集mAP50很高、验证集却极低相差超过0.3。原因2.1节提到的随机划分把连续采集的猴子图片按时间切片分开了同一只猴子的不同姿态大量进了训练集验证集只剩下远距离小目标难度天然更高。这是典型的“看着过拟合其实是分布撕裂”。解决改用文件名哈希或按拍摄时间分组划分保证验证集里包含不同距离、不同姿态的猴子。如果压缩包里本身带了train/valid目录直接沿用但先看两边图片数量比例是否合理别迷信原作者的划分。这个坑在迁移学习场景里特别容易翻车因为预训练权重会把背景先验带进来分布失衡会被误读成过拟合。4.4 小目标猴子被数据增强误伤现象训练集里标注框面积小于32x32的猴子验证时几乎全漏掉。原因YOLO默认的mosaic、mixup、随机裁剪会把小目标裁掉或缩得更小增强后样本里小目标的有效面积进一步缩水模型学不到特征。4690张图中如果大量是远距离小猴子这个问题会非常突出。解决在训练命令里关掉mixup把mosaic保留但调低概率或者对标注框面积做统计低于某个阈值时用滑窗把图裁成多块再训练。我一般会在data.yaml里不做改动而是在命令行加mixup0.0然后观察验证集小目标召回。如果确实要提升小目标能力除了增强调整部署时用滑窗推理是性价比更高的方案成本比重新标注小目标低得多。4.5 预训练权重选错初始loss高得离谱现象用yolov8n.pt训练时第一个epoch的cls_loss就超过3.5后面下降很慢。原因yolov8n.pt是在COCO上预训练的COCO的类别里没有“猴子”但包含猴子所在的大类背景。如果直接用modelyolov8n.pt没问题问题往往出在下载了一个只训练了少量epoch的中间权重或者把检测头和分类头错误地冻结住了。解决重新下载官方yolov8n.pt或者干脆不加model参数让框架自动初始化。如果必须冻结backbone只冻结前10层别把整个backbone全冻住猴子这种细粒度类别完全冻结backbone会让特征停留在COCO的通用语义上分类边界学不好。这个坑的排查方法是训练第一个epoch后打开results.png看box_loss是否在1.0附近如果远超这个数多半是权重来源不对。注意上述坑都在日志里有迹可循。遇到玄学精度问题时先看数据分布再看参数最后才怀疑代码顺序反了会浪费大量时间。训练稳定后很多人以为把best.pt拿出去用就行。实际上4690张图训出的模型在真实场景里一定会遇到没见过的背景和目标尺度。下面这步是把数据集价值榨干的阶段。5. 把4690张图的价值榨干小样本微调与难例挖掘5.1 用预训练权重做第二阶段微调别从零训练4690张图如果在复杂背景下只训60轮模型对猴子的姿态泛化是不够的。常见的做法是拆两阶段第一阶段用COCO预训练权重在整份数据上训练得到best.pt第二阶段用best.pt作初始化在你的实际场景数据上再微调几十轮。这样做的原理是第一阶段的模型已经把猴子的纹理、姿态先验学得差不多第二阶段只需要修正背景和光照差异收敛快且不容易破坏已有特征。from ultralytics import YOLO # 第一阶段 model YOLO(yolov8s.pt) model.train(datamonkey_dataset/data.yaml, epochs60, imgsz640, batch8, projectruns_monkey, namestage1) # 第二阶段用stage1的best.pt初始化 model2 YOLO(runs_monkey/stage1/weights/best.pt) model2.train(datamonkey_dataset/data.yaml, epochs40, imgsz640, batch8, projectruns_monkey, namestage2, lr00.0005)第二阶段的lr0比默认的0.01低一个量级目的是在已经收敛的特征空间里做精细调整lr00.0005是个保守但安全的起点。这里data.yaml还是同一份如果你的实际场景图像和zip里差别大把新采集的几百张图直接放进train/images再划分一次微调效果会明显比只用旧数据好。用预训练权重微调时有个容易忽略的点不要让resume直接接着跑。resumeTrue会连优化器状态一起恢复如果换了数据集优化器的历史梯度会拖慢收敛常见做法是只加载weights重新建优化器。ultralytics的YOLO(path)加载权重就是这么做的所以第二阶段要新建model2而不是在原model上调用train(resumeTrue)。5.2 难例挖掘把漏检样本拉回来训练训练完第一版模型后最简单的验证方式是对训练集做一次预测把置信度低于0.3的检测框和图片导出来看。这些难例里有的是猴子被树叶挡住一半有的是猴子和树干颜色接近有的是多只猴挤在一起。把它们挑出来人工确认标注是否准确再重训一版往往比盲目增加数据集更有效。这也是把4690张带标签数据用出上限的关键一步。from ultralytics import YOLO from pathlib import Path import shutil model YOLO(runs_monkey/stage1/weights/best.pt) img_dir Path(monkey_dataset/train/images) hard_dir Path(hard_examples) hard_dir.mkdir(exist_okTrue) for img_path in list(img_dir.glob(*.jpg))[:500]: # 先抽500张做排查避免一次全跑 result model.predict(str(img_path), conf0.3, verboseFalse)[0] low_conf [b for b in result.boxes if b.conf.item() 0.3] if len(result.boxes) 0: shutil.copy(img_path, hard_dir / (no_det_ img_path.name)) elif low_conf: shutil.copy(img_path, hard_dir / (low_conf_ img_path.name))这段脚本对前500张训练图做预测把完全没检测到猴子的图和存在低置信度框的图都复制到hard_examples目录。conf0.3是置信度阈值可以根据验证集的F1曲线调整如果漏检多可以把阈值降到0.1否则低置信度框会被过滤掉看不到真正的难例。verboseFalse避免每张图打印一行日志跑起来更干净。难例挖掘毕竟是半自动流程脚本负责圈定候选人负责看图和修正标签。我一般会保留三次难例挖掘的目录每次重训后对比难例数量是否减少。如果某一轮难例数量不再下降说明模型已经把这批数据的表达能力用尽接下来该补新场景的数据而不是继续在同一份zip上反复训练。这也符合目标检测数据集迭代的普遍规律标注质量、场景多样性和训练轮数三者缺一不可。6. 猴子检测模型怎么验证才靠谱mAP之外的具体指标训练完成后我很少只拿mAP50交差。猴子检测这类单类目标检测真正要验证的是三个点低置信度阈值下的召回率、误检率、以及连续视频帧上的稳定性。也就是模型在跌跌撞撞的监控画面里能不能稳稳跟住目标。验证方法很简单抽一段模型没见过的视频按每隔10帧抽一帧的方式跑推理统计检测框中心点在相邻帧之间的位移。如果中心点跳动超过框宽的一半说明单帧检测不稳定靠的是偶然命中而不是特征学习。用best.pt对验证集做批量预测时我还会专门看置信度在0.1到0.5区间里的分布。正常模型会有一条明显的双峰曲线大量高置信度的正样本加上少量低置信度的背景误检。如果曲线在0.2附近堆成一团说明模型对猴子和非猴子没有形成清晰边界此时调conf阈值是治标去补难例数据才是治本。这个经验来自一次被景区树叶误检折磨的实际项目。部署时还有一个容易忽略的指标单线程推理耗时。猴子检测常用在边缘盒子或摄像头本地yolov8s在CPU上跑一张640x640的图往往要150毫秒以上而yolov8n可能只要70毫秒。如果现场对延迟敏感我的习惯是先量化再看精度用INT8量化验证量化后mAP50掉点不超过2%再决定上线。这个流程走下来比在任务里反复调超参数靠谱得多。我自己的血泪经验是数据集标题写4690张不代表训练一次就能结束。拿到手先盘数据、再跑通基线、然后做难例挖掘这套流程下来最后交付的best.pt才是能拿给现场用的。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

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

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

你可能需要的服务

订阅华诺云谱资讯周报

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

↑