
简介一套面向蟑螂目标检测任务的数据集包含374张已标注图片标注类别统一为蟑螂适合计算机视觉学习者、算法工程师用于训练与评估主流目标检测模型也适用于智能害虫监测、消杀机器人等实际视觉项目。压缩包共1124个文件主要包含JPG原图、Pascal VOC格式的XML标注文件、YOLO格式的TXT标注文件整体大小仅12.29MB便于快速下载和本地解压使用。所有图片均采集自百度网页使用labelImg工具人工绘制矩形边界框且已经过多轮准确性核实数据集总标注框数达943个单个类别标注信息完整可放心用于模型训练或迁移学习。目前已有78人学习/下载对于需要快速获取高质量小样本数据的开发者而言可显著节省从数据采集、清洗到标注的时间双格式标签还能直接对接到不同训练管线是一份上手门槛低的实用数据集。1. 蟑螂检测数据集370张VOCYOLO格式小样本目标检测的一次完整落地半夜厨房开灯一只蟑螂窜进橱柜缝你掏出手机想拍清楚它已经不见了。换成视觉检测设备情况也差不多蟑螂体色深、行动快、喜欢贴在墙角缝隙里常规目标检测模型很难在小尺寸、低照度下稳定框住它。这个标题里的数据集就是冲着这类特定场景来的——370张带标注的蟑螂图片同时用VOC和YOLO两种格式存储拿到手可以直接喂给YOLO系列做训练或微调不用再花几个晚上写标注工具、统一格式。它的价值不在数据量而在“正好够跑通一次完整流程”。370张图对深度学习来说是小样本但对刚入门的开发者、做毕业设计的学生、或者想给卫生害虫监测设备做验证的工程师这个体量恰好能把数据整理、格式转换、训练调参、评估迭代整条链路走一遍。适合两类人一类是只想搞清楚YOLO训练自己数据集每一步该怎么做的新手另一类是已经在做害虫识别但缺种子数据、想快速验证方案可行性的从业者。接下来我会按照拿到zip之后的实际操作顺序把它从解压到训练的完整路径拆开讲重点落在格式转换和踩坑点上。2. VOC与YOLO两种标注格式先看懂再动手别急着解压2.1 VOC格式的结构xml里藏着一张图的全部标注信息VOCPascal VOC是目标检测领域最经典的标注格式之一它的核心思路是“一张图片配一个同名的XML文件”。解压之后你通常会看到两个并列的目录JPEGImages存放jpg图片Annotations存放xml文件。每一个xml文件里记录了对应图片的文件名、尺寸通道数、以及每一个目标物体的类别和边界框坐标。下面是一个典型的VOC标注内容annotation folderJPEGImages/folder filenamecockroach_001.jpg/filename size width640/width height480/height depth3/depth /size object namecockroach/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin120/xmin ymin80/ymin xmax300/xmax ymax260/ymax /bndbox /object /annotationXML结构中需要注意三个关键点filename要和图片文件名完全一致包括扩展名size里的宽高是绝对像素值转换格式时依赖这个值bndbox里的四个坐标xmin、ymin、xmax、ymax也是绝对像素值。另外difficult字段很实用表示该目标是否难以辨认比如被遮挡、太小看不清很多转换脚本会默认跳过difficult1的目标避免它们干扰训练。VOC格式的优势是可视化友好直接用labelImg或任何XML解析库都能打开查看缺点也明显——每个目标都要写一段XML一张图五六个蟑螂就是五六个object块文件冗余且解析略重。所以在实际训练时很少有人直接把VOC喂给YOLO系列都是先转成YOLO格式的txt文件。2.2 YOLO格式一行文本搞定一个目标归一化坐标是关键YOLO格式和VOC最大的区别在于每张图片对应一个同名txt文件每一行只描述一个目标五个数字分别是类别id、归一化中心点x、归一化中心点y、归一化宽度、归一化高度。归一化意味着所有值都除以图片的宽或高取值范围在0~1之间。还是一张640x480的图蟑螂边界框xmin120、ymin80、xmax300、ymax260对应的YOLO格式是0 0.328125 0.354167 0.281250 0.375000计算过程中心点x (120300)/2 / 640 210/640 0.328125中心点y (80260)/2 / 480 170/480 ≈ 0.354167宽度(300-120)/6400.28125高度(260-80)/4800.375。类别id为0对应类别列表里的第一个名字通常是cockroach。这样每一行都不依赖图片尺寸训练时YOLO读取图片后会按照自己的输入尺寸缩放目标位置不会错位。使用YOLO格式时图片和txt是分开存放的。典型的目录布局是images/train、images/val、labels/train、labels/val图片和对应的txt文件名必须完全一致只是扩展名不同。这也是新手最容易翻车的地方严格区分大小写、不能有多余空格文件名对不上就直接报找不到label。对比项VOC格式YOLO格式存储载体XML文件txt文件坐标形式绝对像素xmin, ymin, xmax, ymax相对坐标x_center, y_center, width, height是否归一化否是全部除以图片宽高类别表示字符串如cockroach整数id从0开始单图多目标多个object块每行一个目标训练时读取需解析XML直接按行读取速度更快该数据集同时提供两种格式本质上是考虑到不同的使用路径想用torchvision里的Faster R-CNN可以直接读VOC格式想用YOLOv5、YOLOv8直接读txt。如果你拿到手的只有其中一种后面这段转换脚本就是另一个常用方案。2.3 VOC转YOLO格式写一个脚本处理一个目录一劳永逸假设你拿到手的只有VOC格式或者你自己用labelImg标了一批蟑螂图片需要一个批量转换脚本。常见做法是写一个Python脚本遍历Annotations目录下所有xml逐个解析出目标坐标再除以图片宽高写入同名txt。下面这个脚本可以直接放到数据集根目录下运行import os import xml.etree.ElementTree as ET def convert_voc_to_yolo(xml_dir, output_dir, class_names): 将VOC格式的xml标注转换为YOLO格式的txt标注 xml_dir: 存放xml文件的目录 output_dir: 存放txt文件的目录 class_names: 类别名称列表索引即类别id os.makedirs(output_dir, exist_okTrue) class_name_to_id {name: idx for idx, name in enumerate(class_names)} for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue xml_path os.path.join(xml_dir, xml_file) tree ET.parse(xml_path) root tree.getroot() img_width int(root.find(size/width).text) img_height int(root.find(size/height).text) txt_lines [] for obj in root.findall(object): name obj.find(name).text difficult int(obj.find(difficult).text) if difficult 1: continue # 跳过难以辨认的目标 if name not in class_name_to_id: continue # 类别不在列表内则跳过 class_id class_name_to_id[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 / img_width y_center (ymin ymax) / 2 / img_height width (xmax - xmin) / img_width height (ymax - ymin) / img_height txt_lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) txt_name os.path.splitext(xml_file)[0] .txt with open(os.path.join(output_dir, txt_name), w) as f: f.write(\n.join(txt_lines)) if __name__ __main__: convert_voc_to_yolo( xml_dirAnnotations, output_dirlabels_full, class_names[cockroach] )这段脚本的核心逻辑是先建立类别名称到id的映射然后解析每个xml拿到图片尺寸再遍历所有object标签把绝对坐标转成归一化坐标。这里有两个参数需要根据实际情况调整class_names列表里的顺序决定了txt中类别id的含义如果数据集里有其他类别比如roach_egg、dead_cockroach必须把全部类别名称按固定顺序写进去否则后面训练时类别就乱了difficult字段按需保留如果你的场景里蟑螂都被遮挡了一半那difficult1的目标其实很有训练价值建议不跳过。反向转换YOLO转VOC也是常见需求。做法是解析txt每一行的五个数值乘以图片宽高还原绝对像素坐标再构造XML节点。需要注意YOLO格式存储的是中心点坐标要还原成xmin、ymin时记得减去半宽半高不然框的位置整体偏移半个目标大小。3. 用YOLOv8在本地跑通370张蟑螂检测最小训练流程3.1 数据集目录统一图片和标签按比例拆分一个脚本搞定拿到zip并解压后第一件事不是急着训练而是把目录结构统一成YOLO训练的约定样式。370张图如果不拆分全部丢进去训练最后连验证集都没有根本不知道模型效果如何。常见的做法是按8:2或9:1划分训练集和验证集同时保证图片和对应标签文件同步移动。import os import random import shutil random.seed(42) # 固定随机种子保证每次划分一致 image_dir JPEGImages label_dir labels_full train_ratio 0.8 train_img_dir images/train val_img_dir images/val train_label_dir labels/train val_label_dir labels/val for d in [train_img_dir, val_img_dir, train_label_dir, val_label_dir]: os.makedirs(d, exist_okTrue) images [f for f in os.listdir(image_dir) if f.endswith((.jpg, .jpeg, .png))] random.shuffle(images) split_idx int(len(images) * train_ratio) for img in images[:split_idx]: label os.path.splitext(img)[0] .txt shutil.copy(os.path.join(image_dir, img), train_img_dir) shutil.copy(os.path.join(label_dir, label), train_label_dir) for img in images[split_idx:]: label os.path.splitext(img)[0] .txt shutil.copy(os.path.join(image_dir, img), val_img_dir) shutil.copy(os.path.join(label_dir, label), val_label_dir) print(f训练集: {len(images[:split_idx])} 张, 验证集: {len(images[split_idx:])} 张)这个脚本的核心参数是train_ratio0.8和random.seed42。随机种子固定以后每次运行划分结果都一样这很重要——当你调整了训练参数想对比效果时必须保证训练集和验证集完全相同否则结果差异无法归因。另外我用的是shutil.copy而不是move保留原始目录不动方便后续补标数据后重新划分。有个细节值得注意解压后的标签文件名可能是.txt但有些第三方工具会生成.txt之外的后缀比如.json或.xml。划分脚本里label os.path.splitext(img)[0] .txt这个拼接逻辑只对纯txt有效如果你的标签是其他格式先做一次批量重命名再划分。3.2 配置data.yaml文件类别名称顺序必须和txt里的id完全一致划分完目录后需要写一个data.yaml告诉YOLOv8去哪里找图片、一共几类、类别叫什么名字。这个文件放在数据集根目录下即可内容如下path: /home/user/cockroach_dataset train: images/train val: images/val names: 0: cockroachpath指向数据集根目录的绝对路径train和val是相对于path的子目录。names这个字典值得多说两句字典里的索引必须是从0开始的连续整数而且顺序要和txt文件里的类别id完全一致。比如txt里类别id为0的行代表蟑螂那么names里0: cockroach如果txt里出现id为1但names里没有定义训练不会报错但推理出来全是未命名类别混淆矩阵根本没法看。还有一个可选字段是nc类别数量。YOLOv8会自动根据names的长度推断所以不写也行但如果你用的某个修改版训练脚本或者搞混了names和nc建议手动加上nc: 1多看一步没有坏处。3.3 训练命令和关键参数小模型起步看loss也看PR曲线一切就绪后执行训练命令。以YOLOv8为例最小可用命令是yolo detect train \ modelyolov8n.pt \ data/home/user/cockroach_dataset/data.yaml \ epochs100 \ imgsz640 \ batch8 \ patience30这条命令里每个参数都有讲究。modelyolov8n.pt是YOLOv8纳米版预训练权重只有约3.2M参数370张图的小数据集用nano最稳妥如果你用yolov8x.pt这种大模型大概率严重过拟合loss降不下去还特别慢。imgsz640是输入分辨率如果原图里的蟑螂很小比如宽度不到30像素建议升到1280再训练代价是显存占用翻倍、训练时间变长后面第5章会展开讲小目标处理。batch8取决于显卡显存6G显存跑nano加640分辨率基本是上限显存不够就把batch降到4不要硬撑。patience30表示在验证集上连续30个epoch没有提升就提前停止小数据集通常训练不到100个epoch就停了属于正常现象。训练结束后在runs/detect/train目录下会生成weights/best.pt和weights/last.pt。评估一个蟑螂检测模型好不好不要只看loss曲线——loss下降只代表模型在训练集上拟合了真正要关注的是results.png里的mAP50曲线以及验证集上的P精准率和R召回率。蟑螂检测的特点是漏检代价比误报更大没框到等于放任不管框错了最多是空报一次。所以调参时我会更看重召回率R至少要跑到0.75以上才敢拿到真实场景用。4. 数据集落地避坑5个高频翻车点与排查方法4.1 解压后图片比标注少或者txt数量对不上标注丢失还是文件名错位现象解压后JPEGImages里有370张jpg但Annotations里只有365个xml打开某些txt一看里面是空的。原因数据集制作时可能漏标了几张图片或者标注工具批量导出时跳过了一些没有目标的图片。空txt文件在YOLO训练里不会报错但会让模型学到“这张图什么也没有”直接影响准确率。解决用脚本统计每张图片对应的txt行数行数为0的单独拎出来检查。import os label_dir labels_full empty_labels [] for f in os.listdir(label_dir): if f.endswith(.txt): path os.path.join(label_dir, f) if os.path.getsize(path) 0: empty_labels.append(f) print(f空标注文件: {len(empty_labels)} 个) for f in empty_labels[:10]: print(f)如果确认图片里确实没有蟑螂就把对应的图片也移出训练目录或者保留在验证集里当负样本用如果图片里有蟑螂但txt是空的说明标注确实丢了要用labelImg重新打开这张图补标。4.2 训练时报错“not found”图片和标签的路径配置错了现象训练刚开始几秒就退出控制台提示assertion failed: ... not found经常是一长串图片路径。原因最常见的是data.yaml里的path写的是相对路径而YOLOv8在解析时把它当成了相对于当前工作目录的路径你从其他目录运行训练命令就找不到。另一个高发原因是图片是.jpg但txt是.JPGLinux下区分大小写直接报错。解决把data.yaml里的path改成绝对路径并且确认JPEGImages目录下的图片扩展名到底是.jpg还是.jpeg还是.png用一条命令统一find /home/user/cockroach_dataset -name *.JPG -exec rename s/\.JPG$/.jpg/ {} \;4.3 训练正常但mAP一直是0loss也不降类别id错位现象训练日志里mAP50始终为0P、R也是0但loss曲线在缓慢下降训练没有中断。原因数据集txt里的类别id和data.yaml里names的索引对应不上。比如txt里写的是1 0.32 0.45 0.11 0.22而names只定义了0: cockroach模型把id1当成一个不存在的类别自然永远无法正确识别。解决把txt第一列的所有取值打印出来和names的索引做对比。awk {print $1} labels/train/*.txt | sort | uniq -c这个命令输出每个类别id出现的次数如果出现了超过names长度的id用脚本批量修正sed -i s/^1 /0 /g labels/train/*.txt labels/val/*.txt注意sed里的^1是匹配行首的“1 ”如果替换成0一定要带空格避免把坐标值里的数字也改了。4.4 输入尺寸引起的标注失配imgsz和原图宽高比例差太多现象训练没报错mAP也还行但推理时框的位置明显偏了尤其图片边缘的蟑螂框总是叠不紧。原因原始图片分辨率是1920x1080蟑螂目标只占很小一块YOLOv8在训练时把图缩放到640x640小目标被压缩成几个像素标注框也跟着失真。这类问题在370张的小数据集中尤其明显。解决训练时把imgsz改成1280同时给模型足够多的epoch去适应新分辨率。如果显存不够先把图片按2x2切块再训练相当于把一张大图拆成4张子图目标相对变大模型更容易学到蟑螂的身体纹路特征。4.5 验证集指标挺好换个环境就废数据分布太单一现象验证集mAP50在0.9以上结果把训练好的模型拿到厨房实地一测亮光下还行到了黄昏时段或者深色橱柜背景里框得七零八落。原因370张图可能全部来自同一个拍摄环境比如实验室白炽灯下拍的白墙背景。深度学习模型很傻它可能学到了“亮背景特定反光蟑螂”换到偏暗的厨房环境特征分布变了检测率直线下降。解决以后采集数据时主动覆盖不同场景——白天、夜晚、开灯、不开灯、瓷砖墙、木质橱柜、水泥地面。当前数据集不够的话可以对图片做色彩抖动和亮度扰动来模拟不同光照但这是治标不治本真实场景迁移只能靠更多样的数据。实际操作中我把训练好的模型先跑一遍数据集外的10张厨房实拍图看它的置信度分布凡是低于0.3的基本要当作漏检来追查。5. 370张图怎么榨出更高精度迁移学习、数据增强与真实场景验证5.1 先复现再调参第一个模型只用来跑通流程从零训练一个yolov8s要几万张图370张图直接随机初始化训练结果会很惨。正确做法是用预训练权重做迁移学习——yolov8n.pt已经在ImageNet上见过大量基础视觉特征我们把它的特征提取层冻结起来只训练检测头几个epoch让模型先适应蟑螂的颜色纹理。具体命令yolo detect train \ modelyolov8n.pt \ data/home/user/cockroach_dataset/data.yaml \ epochs50 \ freeze10 \ imgsz640 \ batch8freeze10表示冻结模型前10层这些层学到的是边缘、纹理、形状这些通用特征对蟑螂依然有效。等第一个模型跑通验证流程后再解冻全部层用一个较小的学习率比如lr00.001微调20个epoch。不要一上来就用默认学习率训练全部参数370张图很容易让预训练权重在几个epoch内被破坏。5.2 数据增强参数的几个关键旋钮翻转变换要看场景合不合理YOLOv8在训练参数里内置了数据增强配置合适设置相当于把370张图扩成几千张。以下是我在蟑螂检测场景下常用的几个参数yolo detect train \ modelyolov8n.pt \ data/home/user/cockroach_dataset/data.yaml \ epochs60 \ imgsz640 \ batch8 \ hsv_h0.015 \ hsv_s0.5 \ hsv_v0.4 \ fliplr0.5 \ scale0.5hsv_h0.015表示色调轻微扰动蟑螂的深褐色不需要大改色调幅度太大会让模型学到草绿色蟑螂hsv_s0.5和hsv_v0.4分别控制饱和度和明度这个幅度可以模拟夜间暗光或强光照射的情况。fliplr0.5左右翻转是安全的因为蟑螂左右对称但不要用flipud上下翻转厨房的蟑螂不会出现在天花板视角加了之后模型会把地板上的蟑螂和天花板上的蟑螂当成同一种特征反而有害。scale0.5允许图片随机缩放这能模拟镜头远近变化但缩放比例不要超过0.7否则小目标直接被压缩到看不清起不到增强作用。调参时记住一个原则增强策略要贴合目标在真实世界的分布不是为了增强而增强。5.3 一个可落地的验证技巧拿10张“外场照片”测泛化能力训练和调参到头来都要回答一个问题这个模型放在真实厨房里能不能用。我的习惯是单独留10张从未参与训练、来自不同环境的蟑螂照片做测试用训练好的模型跑一次推理看置信度分布然后统计低置信度的框都集中在什么位置。yolo predict \ modelruns/detect/train/weights/best.pt \ source/home/user/cockroach_dataset/external_test/ \ conf0.25 \ save_txtTrue如果这10张外场照片的平均置信度只有0.3说明模型已经过拟合训练集了如果平均置信度在0.6以上这个模型基本可以进入实地部署验证阶段。conf0.25是推理时的置信度阈值实际部署时我会调高到0.4以上来降低误报因为蟑螂检测器误报的代价是让后端设备空转容易造成维护疲劳。还有一个血泪经验验证时不要只看画了框的图片要看置信度的分布而不是单纯框得准不准。有时候模型框得很准但置信度只有0.2距离落地还差着一段调优的路。370张数据集的定位不是让你一步登天搞出99%准确率的系统而是让你把流程走透、踩坑踩完后续补数据有清晰方向。我自己的习惯是在数据集的目录里放一个README.md记录每一次训练的配置参数、结束时的mAP和踩过的坑等需要复现时不用重新试错。希望这份拆解能帮你在自己的数据集上少走几趟弯路。本文还有配套的精品资源点击获取