简介这份资源面向计算机视觉入门与进阶学习者、课程设计及科研人员提供一套可直接用于YOLO系列目标检测训练的垃圾分类数据集。数据均为真实场景采集覆盖多种复杂环境使用labelimg精细标注标注框质量较高并同步提供vocxml、cocojson与yolotxt三种格式标签分别存放于独立文件夹便于直接接入不同训练框架。压缩包共约2000个文件以1985个xml标注文件为主另含少量txt、html与py脚本整体约410MB目录结构清晰。资源还附赠数据集划分脚本可按需生成训练集、验证集与测试集并配套Windows与Linux环境搭建及训练案例教程帮助读者快速跑通从环境配置到模型训练的全流程。目前已有1346人学习下载适合需要快速验证算法、完成课程作业或开展垃圾分类检测实验的读者参考使用。1. 一万张垃圾图 三格式标签这套 YOLO 数据集到底能不能直接开训手上接到一个垃圾分类检测的活儿第一反应往往不是选模型而是找数据。自己拍、自己标、自己转格式一万张图走完这套流程两周就没了。这套资源的核心价值就在这儿10000 张真实场景垃圾图片labelImg 标注voc(xml)、coco(json)、yolo(txt) 三种标签格式分文件夹放好外加划分脚本和 Windows/Linux 双版本环境搭建与训练教程。它解决的是「数据从哪来、格式怎么统一、训练怎么起步」这三个最耗时的环节。适合刚接触 YOLO 目标检测、想跑通自己第一个垃圾分类模型的工程师也适合手上有算法但缺数据的团队直接拿来做 baseline。下面我按「数据长什么样 → 怎么划分 → 怎么配环境 → 怎么训 → 坑在哪」的顺序拆一遍。2. 三格式标签与目录结构先搞清楚手里到底有什么2.1 voc、coco、yolo 三种标签的差异与选用这套数据集最省事的地方是同一批标注同时给了三种格式。很多人拿到手第一反应是「我该用哪个」答案取决于你走哪条训练链路。voc 格式是每张图对应一个 xml 文件里面用object节点记录类别名和xmin/ymin/xmax/ymax四个角点坐标坐标是绝对像素值。coco 格式是一个大的 json用images、annotations、categories三个数组组织bbox 是[x, y, width, height]且为绝对像素。yolo 格式是每张图一个 txt每行类别索引 cx cy w h全部归一化到 0~1。选型上如果你用 ultralytics 系的 YOLOv5/v8直接吃 yolo 格式最省事不用转。如果你要用 mmdetection 或者做 COCO 指标评测coco json 更顺。voc 更多是历史遗留和 labelImg 的原生输出适合做格式转换的中间态。三种格式并存的好处是你不需要为了换框架重新标一遍。格式文件形态坐标类型典型用途voc每图一个 xml绝对像素labelImg 原生、转换中间态coco单个 json绝对像素mmdetection、COCO 评测yolo每图一个 txt归一化 0~1YOLOv5/v8 直接训练2.2 目录组织与类别索引对齐拿到压缩包解压后常见做法是 images 和 labels 平行放labels 下再按格式分。这里有个血泪经验yolo 的类别索引是纯数字0 0.53 0.41 0.22 0.18这种它本身不带类别名。类别名和索引的映射关系通常写在classes.txt或者data.yaml里。如果你自己重新排了类别顺序而 txt 里的索引没跟着改训练时模型学到的就是错位的类别loss 能降但预测全是乱的。所以第一步不是急着训是先确认三件事类别总数是多少、classes.txt里的顺序是什么、yolo txt 里出现的最大索引有没有超过类别数减一。用一段脚本几秒钟就能查完import os label_dir labels/yolo classes_file classes.txt with open(classes_file, r, encodingutf-8) as f: classes [line.strip() for line in f if line.strip()] print(f类别数: {len(classes)}, 类别: {classes}) max_idx -1 bad_files [] for name in os.listdir(label_dir): if not name.endswith(.txt): continue with open(os.path.join(label_dir, name), r) as f: for line in f: parts line.strip().split() if not parts: continue idx int(parts[0]) max_idx max(max_idx, idx) # 坐标必须在 0~1 之间越界说明标注或转换有问题 coords [float(x) for x in parts[1:5]] if any(c 0 or c 1 for c in coords): bad_files.append(name) break print(f最大类别索引: {max_idx}) print(f坐标越界文件数: {len(bad_files)}) if bad_files[:5]: print(示例:, bad_files[:5])这段脚本干两件事一是把类别数和索引上限对一下二是扫一遍所有 yolo txt 的坐标有没有越界。归一化坐标理论上都在 0~1出现负数或大于 1要么是标注时框拖出了图外要么是转换脚本算错了。越界框在训练时会被裁掉或者产生异常梯度早发现早处理。参数上label_dir指向你的 yolo 标签目录classes_file指向类别名文件路径按实际解压位置改。3. 数据集划分脚本train/val/test 怎么切才不翻车3.1 三个划分脚本的分工资源里给了三个划分脚本名字就能看出用途训练集、验证集、测试集划分脚本是三路切分训练集、验证集划分脚本是两路切分split_train_val生成ImageSets下txt文件划分脚本是生成 ImageSets 目录下 txt 清单的。前两个是「把图片和标签复制/移动到新文件夹」第三个是「只生成文件名清单不动原文件」。这两种思路差别很大。复制式划分会实实在在产生三份图片副本磁盘占用翻倍甚至三倍但好处是每个子集独立、不会互相干扰。清单式划分只写 txt训练时靠 txt 里的路径去读原图省空间但要求你的训练代码支持从清单读。YOLOv5/v8 默认是按目录读的所以如果你用官方训练脚本复制式更直接如果你自己写 DataLoader清单式更灵活。我一般会先跑清单式确认划分比例合理再决定要不要落成物理副本。因为划分这事最怕的是「切完发现某类样本在验证集里几乎没有」那时候再改就得重来。3.2 按 8:1:1 切分并保持类别分布随机切分有个隐蔽的坑小类别可能被随机切没了。垃圾分类里如果有个类别只有几十张图纯随机切分很可能验证集里一张都没有训出来的模型在这个类上没法评估。稳妥做法是按类别分层抽样。下面这段是常见的分层划分写法import os import random import shutil from collections import defaultdict random.seed(42) # 固定种子保证可复现 img_dir images label_dir labels/yolo out_root dataset_split train_ratio, val_ratio 0.8, 0.1 # 剩下 0.1 给 test # 按类别归组一张图可能含多个类别取第一个类别作为分层依据 cls_to_imgs defaultdict(list) for name in os.listdir(label_dir): if not name.endswith(.txt): continue stem os.path.splitext(name)[0] with open(os.path.join(label_dir, name)) as f: lines [l for l in f if l.strip()] if not lines: continue main_cls int(lines[0].split()[0]) cls_to_imgs[main_cls].append(stem) for split in [train, val, test]: os.makedirs(os.path.join(out_root, split, images), exist_okTrue) os.makedirs(os.path.join(out_root, split, labels), exist_okTrue) for cls, stems in cls_to_imgs.items(): random.shuffle(stems) n len(stems) n_train int(n * train_ratio) n_val int(n * val_ratio) buckets { train: stems[:n_train], val: stems[n_train:n_train n_val], test: stems[n_train n_val:], } for split, items in buckets.items(): for stem in items: shutil.copy(os.path.join(img_dir, stem .jpg), os.path.join(out_root, split, images, stem .jpg)) shutil.copy(os.path.join(label_dir, stem .txt), os.path.join(out_root, split, labels, stem .txt)) print(划分完成)逻辑上先按主类别把图片分组再在每组内部按比例切这样每个类别在三个子集里都有代表。random.seed(42)是后悔药保证你下次跑结果一样方便复现和排查。train_ratio和val_ratio按需改剩下自动归 test。图片扩展名这里写死.jpg如果你的图是.png或.jpeg得改成对应后缀或者用os.path.splitext动态取。这一步跑完dataset_split下就是标准的三份数据可以直接喂给 YOLO。提示划分前先备份原始标签目录。复制式脚本一旦路径写错可能把源文件覆盖掉这种翻车我见过不止一次。4. 环境搭建与训练Windows 和 Linux 两条路怎么走4.1 环境搭建的关键依赖与版本对齐资源里给了 Windows 和 Linux 两套环境搭建教程还有 Ubuntu 安装教程。核心依赖就那几个Python、CUDA、cuDNN、PyTorch、ultralytics。真正容易出问题的不是装不上是版本对不齐。PyTorch 的 CUDA 版本必须和系统驱动支持的 CUDA 版本匹配否则torch.cuda.is_available()返回 False训练直接掉到 CPU 上一万张图能跑到你怀疑人生。常见做法是先nvidia-smi看驱动支持的最高 CUDA 版本再去 PyTorch 官网找对应版本的安装命令。比如驱动支持 CUDA 12.1就装 cu121 的 torch。装完立刻验证python -c import torch; print(torch.__version__, torch.cuda.is_available(), torch.cuda.get_device_name(0))输出里True和显卡型号都在才算环境通了。如果显示 False先别急着训回去查驱动和 torch 版本。这一步省下来的时间比后面调参省的多。4.2 用 data.yaml 接上数据集并启动训练YOLOv5/v8 训练靠一个data.yaml描述数据位置和类别。按第 3 章切好的目录写出来大概是这样path: ./dataset_split train: train/images val: val/images test: test/images nc: 4 names: [recyclable, kitchen, hazardous, other]nc是类别数names顺序必须和 yolo txt 里的索引严格对应第 0 个名字对应索引 0。path是根目录下面的 train/val/test 是相对路径。写完直接起训yolo detect train datadata.yaml modelyolov8n.pt epochs100 imgsz640 batch16model选预训练权重imgsz是输入尺寸batch按显存调显存不够就往下压。训练过程中重点看mAP50和各类的instances数量如果某个类 instances 一直是 0说明划分或标签索引有问题回去查第 2 章那段校验脚本。5. 避坑与排查这几处翻车点我替你踩过了5.1 类别索引错位导致 loss 正常但预测全乱现象训练 loss 平稳下降mAP 却低得离谱预测框位置对但类别全是错的。 原因data.yaml里names的顺序和 yolo txt 里的数字索引没对齐或者你重新排了类别但没改标签。 解决跑第 2 章的校验脚本确认最大索引小于nc再逐行核对names顺序和classes.txt是否一致。改完重新训别在错位的数据上继续调参。5.2 坐标越界引发异常框现象训练日志里偶尔报坐标异常或者可视化时框跑到图外。 原因标注时框拖出边界或 voc 转 yolo 时归一化除错了宽高。 解决用第 2 章脚本扫出越界文件手动重标或裁剪坐标到 0~1。批量处理时把越界值 clamp 到边界但更稳妥是回源头修标注。5.3 验证集某类样本为零现象训练完发现某个类别的 mAP 是 0 或 nan。 原因随机划分把小类别全切到训练集了。 解决改用第 3 章的分层抽样脚本按类别分组后再切。切完统计每个子集各类的图片数确认没有空类。5.4 CUDA 版本不匹配导致训练掉 CPU现象torch.cuda.is_available()返回 False训练速度极慢。 原因PyTorch 的 CUDA 版本和系统驱动不匹配。 解决nvidia-smi看驱动支持版本重装对应 cu 版本的 torch。别用 conda 默认源瞎装容易装到 CPU 版。5.5 图片和标签文件名不一致现象训练时报找不到标签或者部分图被跳过。 原因划分或重命名时图片和 txt 的 stem 没对上比如图是img_01.jpg标签是img_1.txt。 解决写个脚本比对两个目录的文件名集合差集就是问题文件。统一用 stem 匹配扩展名只影响图片读取。6. 进阶用训练好的模型做推理与置信度调优训完模型只是开始真正上线前得会调推理参数。YOLO 推理时有两个关键阈值conf置信度门限和iouNMS 的 IoU 阈值。垃圾分类场景里如果漏检多就把conf调低如果同一个垃圾被框了好几次就把iou调低。这两个参数没有万能值得拿验证集试。yolo detect predict modelruns/detect/train/weights/best.pt sourcetest_images conf0.25 iou0.45 saveTrueconf0.25是常见起点iou0.45控制重叠框合并。跑完看runs/detect/predict下的可视化结果重点看小目标比如烟头、瓶盖有没有被漏掉。如果漏检集中在某一类先别急着调参回去看这一类在训练集里的样本量和标注质量很多时候是数据问题不是参数问题。我一般会在验证集上跑一组 conf 从 0.1 到 0.5 的对比画一条 precision-recall 曲线选 F1 最高的那个点作为上线门限。这套流程走下来模型才算真正能用。从那以后我每次拿到新数据集都强制先跑一遍类别索引校验和划分统计再动训练脚本——这两步花十分钟能省掉后面几小时的无效训练。希望帮到你。本文还有配套的精品资源点击获取
