简介这份垃圾箱数据集面向计算机视觉初学者与目标检测开发者用于训练和验证垃圾箱识别模型可直接接入YOLO、Faster R-CNN等主流框架。资源包共914个文件包含457张jpg图片与457个对应的xml标注文件压缩包约26.79MBrar格式无需解压密码解压后图片与标注分文件夹存放便于直接查看与调用。所有图片均由labelImg人工标注类别统一为dustbin标注过程遵循准确框选目标边界、尽量覆盖全部目标、完成后交叉检查一致性等原则标注质量较为可靠。目前已有94人学习下载。数据集规模适中适合作为检测任务的入门练手或小样本实验素材也可用于验证数据增强、模型微调等流程帮助读者快速搭建训练管线并观察模型在真实场景下的检测表现。1. 垃圾箱数据集 VOC 格式目标标注 457 张小样本检测到底能不能打手上只有几百张标注图是很多做目标检测的工程师最真实的起点。垃圾箱数据集 VOC 格式目标标注 457 张说的就是这么一个场景457 张已经用 VOC 格式标好的垃圾箱图片每张带 XML 标注文件可以直接喂给 YOLO、Faster R-CNN 这类检测器。它解决的不是数据从哪来而是数据少、格式老、类别单一这三件事叠在一起时怎么把模型训到能用。适合谁适合做智慧环卫、园区垃圾满溢识别、边缘盒子部署的从业者也适合刚学完 yolov8训练自己的数据集、想拿一个真实小数据集练手的人。457 张不算多但足够跑通全流程也足够暴露小样本训练里那些玄学问题。2. VOC 格式拆解与 457 张的取舍先看清手里是什么牌2.1 VOC 标注文件里到底存了什么VOC 格式的核心是每张图配一个同名 XML。真正影响训练的字段只有几个filename对应图片名size里的宽高决定归一化基准object下的name是类别bndbox的xmin/ymin/xmax/ymax是绝对像素坐标。很多人拿到数据集直接转格式结果框全偏了八成是size和实际图片尺寸对不上或者坐标写成了 1-based 而代码按 0-based 读。一个典型的垃圾箱 XML 长这样annotation foldertrash/folder filenametrash_0001.jpg/filename size width1280/width height720/height depth3/depth /size object nametrash_bin/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin412/xmin ymin233/ymin xmax690/xmax ymax601/ymax /bndbox /object /annotationdifficult字段在 VOC 评测里表示难样本不计入指标但转 YOLO 时大多数脚本直接忽略它。如果你的数据里有大量遮挡垃圾箱被标了difficult1转完格式后它们会变成正常正样本参与训练模型反而被带偏。我一般会先统计一遍difficult分布再决定要不要过滤。2.2 457 张的分布决定了你的验证集怎么切457 张这个量级最忌讳按 8:1:1 随机切。垃圾箱数据往往来自少数几个固定机位同一机位的连续帧高度相似随机切会让训练集和验证集出现几乎一样的图验证指标虚高。正确做法是按场景或按拍摄批次切比如 5 个点位拿 4 个点位的图训练留 1 个点位做验证。这样验证集才代表没见过的新场景。切之前先做一次分布统计用下面这段脚本快速看清类别和尺寸import os, glob import xml.etree.ElementTree as ET from collections import Counter xml_files glob.glob(Annotations/*.xml) cls_counter Counter() size_list [] for f in xml_files: root ET.parse(f).getroot() w int(root.find(size/width).text) h int(root.find(size/height).text) size_list.append((w, h)) for obj in root.findall(object): cls_counter[obj.find(name).text] 1 print(类别分布:, cls_counter) print(图片总数:, len(xml_files)) print(最小尺寸:, min(size_list), 最大尺寸:, max(size_list))这段脚本只做两件事统计每个类别的框数量以及图片尺寸范围。类别分布严重不均时比如某类只有十几框要么合并类别要么在训练时用类别权重补偿。尺寸范围决定你 resize 到 640 时会不会把小目标压没——垃圾箱通常是大目标问题不大但如果图里有远处的小垃圾箱就要留意。2.3 为什么选 VOC 而不是直接上 COCOVOC 转 YOLO 的脚本满地都是转 COCO 也不难但 457 张这个量级用 COCO 的 JSON 结构纯属给自己找麻烦。COCO 的segmentation、area、iscrowd字段在这个场景里全是冗余标注工具导出还容易出格式错。VOC 的 XML 人眼可读出问题直接打开看改起来也快。常见做法是原始标注保持 VOC训练前用脚本一次性转成 YOLO 的 txt中间不落 COCO。3. 从 VOC 到 YOLO 训练457 张跑通的最小闭环3.1 转换脚本与四个边界坑YOLO 的 txt 格式是class_id cx cy w h全部归一化到 0~1。转换时最容易翻车的地方有四个坐标越界、宽高为负、类别名没映射、图片和标注对不上。下面这个脚本把这四个都处理了import os, glob import xml.etree.ElementTree as ET # 类别名到 id 的映射顺序必须和 data.yaml 里的 names 一致 classes [trash_bin] cls_map {name: i for i, name in enumerate(classes)} def convert(xml_path, out_dir, img_w, img_h): root ET.parse(xml_path).getroot() lines [] for obj in root.findall(object): name obj.find(name).text if name not in cls_map: continue # 未登记类别直接跳过避免 id 错乱 b obj.find(bndbox) xmin float(b.find(xmin).text) ymin float(b.find(ymin).text) xmax float(b.find(xmax).text) ymax float(b.find(ymax).text) # 裁剪到图像范围内防止越界 xmin, xmax max(0, xmin), min(img_w, xmax) ymin, ymax max(0, ymin), min(img_h, ymax) if xmax xmin or ymax ymin: continue # 宽高非法丢弃 cx (xmin xmax) / 2 / img_w cy (ymin ymax) / 2 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_map[name]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) base os.path.splitext(os.path.basename(xml_path))[0] with open(os.path.join(out_dir, base .txt), w) as f: f.write(\n.join(lines)) for xf in glob.glob(Annotations/*.xml): root ET.parse(xf).getroot() w int(root.find(size/width).text) h int(root.find(size/height).text) convert(xf, labels, w, h)关键点cls_map的顺序必须和data.yaml的names完全一致否则类别全错。裁剪到图像范围是必须的VOC 标注里xmax超过图片宽度的情况很常见。宽高非法直接丢不要试图修正修正出来的框是错的。转换完一定要抽查几张用可视化脚本画框确认别信脚本不报错就等于对。3.2 data.yaml 与目录结构YOLO 训练要求固定的目录结构图片和标签分开放路径在 yaml 里配path: /data/trash train: images/train val: images/val nc: 1 names: [trash_bin]目录长这样/data/trash ├── images │ ├── train │ └── val └── labels ├── train └── valnc是类别数names是类别名列表顺序和转换脚本里的classes必须一模一样。path用绝对路径最稳相对路径在不同工作目录下跑容易找不到文件。图片和标签文件名必须同名只是后缀不同YOLO 靠文件名配对配不上就静默跳过训练时表现为某些图没参与很难发现。3.3 训练命令与关键参数用 YOLOv8 训练 457 张的最小命令yolo detect train \ data/data/trash/data.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ patience30 \ projectruns/trash参数说明modelyolov8n.pt用 nano 版457 张数据量小大模型直接过拟合。epochs150配合patience3030 轮验证指标不涨就早停省时间。imgsz640是默认值垃圾箱是大目标640 够用想更快可以降到 416。batch16看显存调显存不够就减到 8 或 4。lr00.01是初始学习率小数据集可以降到 0.005 更稳。训练时重点看mAP50和mAP50-95两条曲线。457 张数据mAP50 能到 0.85 以上就算不错如果卡在 0.5 左右上不去先回去查标注质量别急着调参。4. 小样本训练的避坑清单457 张最容易踩的五个坑4.1 验证指标虚高实际部署一塌糊涂现象训练日志里 mAP50 到 0.95部署到新机位后漏检严重。原因验证集和训练集来自同一批连续帧模型记住了背景而不是目标。解决按机位或时间段切分验证集确保验证集里的场景训练时没见过。切完指标会掉但掉下来的才是真实水平。4.2 类别名大小写不一致导致全部漏检现象训练正常推理时一个框都不出。原因data.yaml里写Trash_Bin转换脚本里写trash_bin类别 id 对不上模型学到的类别和推理时映射错位。解决全流程统一小写转换脚本、yaml、推理代码三处对齐改完重新转一遍标签。4.3 图片和标签文件名对不上静默丢样本现象训练集明明 400 张日志里显示只有 320 张参与。原因部分图片是.JPG大写后缀标签是.txtYOLO 按 stem 配对时大小写敏感配不上就跳过。解决统一后缀为小写用脚本批量重命名重命名后重新核对数量。4.4 学习率太大loss 震荡不收敛现象前几轮 loss 直接飙到 nan 或者剧烈震荡。原因小数据集用默认 lr00.01 偏大batch 又小梯度噪声大。解决lr0 降到 0.005 甚至 0.001同时开cos_lr余弦退火让后期学习率自动降下来。改完还震荡就再减 batch 或加梯度裁剪。4.5 过拟合训练 loss 一直降验证 loss 反弹现象训练集 mAP 接近 1.0验证集停在 0.6 不动。原因457 张对 nano 模型也偏少模型开始背训练集。解决开数据增强mosaic、hsv_h、hsv_s、flipud加weight_decay或者干脆换更小的输入尺寸。增强参数别开太猛垃圾箱的形态变化不大翻转和色调抖动够用mosaic 开 0.5 左右。5. 把 457 张用到极致半自动标注与增量迭代457 张训出来的模型第一版大概率不够用。真正让这个小数据集产生价值的是拿第一版模型去跑未标注的新图做半自动标注再人工修正滚雪球式扩充。具体做法用训好的best.pt对新采集的图做推理把置信度高于 0.6 的框导出成 VOC XML低于阈值的留空让人工补。导出脚本核心是把 YOLO 的归一化坐标反算回像素def yolo_to_voc(cx, cy, w, h, img_w, img_h): xmin int((cx - w / 2) * img_w) ymin int((cy - h / 2) * img_h) xmax int((cx w / 2) * img_w) ymax int((cy h / 2) * img_h) return max(0, xmin), max(0, ymin), min(img_w, xmax), min(img_h, ymax)反算完写回 XML人工只需在标注工具里微调比从零画框快好几倍。每轮扩充 100~200 张重训一次三轮左右模型就能覆盖大部分场景。这里有个血泪经验自动标注的框一定要人工过一遍模型自己标错的框如果直接进训练集下一轮会把错误放大越训越偏。验证模型有没有真的进步别只看 mAP。准备一组固定的难例图——逆光、遮挡、密集堆叠的垃圾箱每次重训后都拿这组图跑一遍肉眼看框。mAP 涨了但难例图没改善说明涨的是简单样本没意义。我一般会把这组难例图单独存一个文件夹当成自己的后悔药每次迭代前先跑它。最后说个习惯457 张这种量级别追求一次训到完美。先把闭环跑通部署一版能用的再靠真实场景的数据回流慢慢迭代。小数据集的价值不在一次训练在于它让你用最低成本验证了整条链路。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?