尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
四类垃圾3000张标注数据集实战:从数据清洗到模型训练全流程
简介这份数据集面向参加生活垃圾智能分类竞赛的选手及计算机视觉学习者提供已完成标注的四类垃圾图像样本可直接用于目标检测模型的训练与验证。压缩包共约2000个文件以1998个XML标注文件为主另含少量txt划分列表整体约411.59MBXML对应每张图像的类别与边界框信息txt则给出训练集与验证集的划分清单便于快速接入YOLO系列流程。数据覆盖有害垃圾电池、过期药品、可回收垃圾易拉罐、小号矿泉水瓶、厨余垃圾小土豆、白萝卜、胡萝卜及其他垃圾瓷片、鹅卵石、砖块等赛题指定类别尺寸与形态贴近实际投放场景。已有1626人学习下载适合需要现成标注数据开展分类识别实验、复现赛题方案或扩充训练样本的读者参考使用。1. 四类垃圾 3000 张已标注数据集拿到手先想清楚它能干什么上周有个做嵌入式视觉的朋友找我说他接了个社区智能垃圾桶的活硬件板子都打样了卡在数据上——自己拍了两周照片标了不到 400 张就崩溃了。我让他先别急着继续标把手上这份四类垃圾约 3000 张的已标注数据集跑一遍基线看看模型到底能不能收敛、类别间到底混不混。结果两小时出第一版 mAP问题立刻暴露可回收物和厨余的混淆率远超预期根本不是数据量不够是标注粒度和拍摄场景的问题。这就是一份现成标注数据集最直接的价值它让你在投入标注人力之前先把「模型能不能学、学到什么程度、卡在哪」这件事验证掉。这份资源是四类生活垃圾的图像数据集总量 3000 张左右已完成标注格式上通常对应目标检测或图像分类两种用法。它适合三类人一是做课程设计或毕业设计、需要快速跑通完整训练流程的学生二是做边缘端垃圾分类 Demo、想先验证算法可行性再决定是否自采数据的工程师三是想拿一个类别边界清晰、规模适中的多分类任务练手数据清洗和增强策略的从业者。3000 张这个量级不算大但四类均分下来每类七百多张做迁移学习够用从零训练不够——这个判断会贯穿后面所有章节。2. 先验数据再动手3000 张的分布、标注格式与清洗口径拿到任何标注数据集我的习惯是先不写一行训练代码而是把数据「看一遍」。3000 张听起来不多但真出问题时八成不是模型结构而是某几类样本严重偏斜、某批图片分辨率异常、或者标注框大面积越界。这一章就是把验收动作做扎实。2.1 目录结构与标注格式的快速盘点常见做法是数据集按类别分文件夹分类任务或者图片与标注文件分离检测任务标注多为 XML、JSON 或 TXT。先跑一段脚本把结构、数量、格式摸清楚比肉眼翻文件夹靠谱得多。import os from collections import Counter from pathlib import Path root Path(./garbage_dataset) # 换成你的实际路径 # 统计每个子目录下的图片数量快速看类别分布 img_ext {.jpg, .jpeg, .png, .bmp} class_counter Counter() for sub in root.iterdir(): if sub.is_dir(): n sum(1 for f in sub.rglob(*) if f.suffix.lower() in img_ext) class_counter[sub.name] n total sum(class_counter.values()) print(f总图片数: {total}) for name, n in class_counter.most_common(): print(f{name}: {n} 张, 占比 {n/total:.1%}) # 检查是否存在标注文件与图片数量不匹配的情况 for sub in root.iterdir(): if not sub.is_dir(): continue imgs {f.stem for f in sub.rglob(*) if f.suffix.lower() in img_ext} labels {f.stem for f in sub.rglob(*) if f.suffix.lower() in {.xml, .json, .txt}} if labels: missing imgs - labels if missing: print(f[警告] {sub.name} 有 {len(missing)} 张图缺标注示例: {list(missing)[:3]})这段脚本干三件事统计总量、按类别算占比、检查图片与标注文件是否一一对应。参数上唯一要改的是root路径和img_ext集合——如果你的数据集是 PNG 为主记得把.png留在集合里。输出里如果某一类占比低于 15%后面训练就得考虑类别加权如果出现「缺标注」警告先别训练把缺的补齐或剔除否则检测任务里这些图会被当成纯背景直接污染负样本。2.2 分辨率、损坏文件与重复样本的排查3000 张来自不同渠道的图分辨率不统一是常态偶尔混进几张打不开的损坏文件也不稀奇。更隐蔽的是重复样本——同一张图换个文件名出现两次训练集和验证集各一份验证指标会虚高这是血泪经验里最常见的一种「假高分」。from PIL import Image import hashlib bad_files, sizes, hashes [], Counter(), {} for f in root.rglob(*): if f.suffix.lower() not in img_ext: continue try: with Image.open(f) as im: sizes[im.size] 1 im.verify() # 校验文件完整性 except Exception as e: bad_files.append((str(f), str(e))) continue # 用文件内容哈希找完全重复的图 h hashlib.md5(f.read_bytes()).hexdigest() hashes.setdefault(h, []).append(str(f)) print(损坏文件:, bad_files[:5], 共, len(bad_files)) print(分辨率分布 Top5:, sizes.most_common(5)) dups {h: v for h, v in hashes.items() if len(v) 1} print(重复组数:, len(dups)) for h, v in list(dups.items())[:3]: print(重复:, v)im.verify()只校验文件头速度快但不够彻底真要严格可以再im.load()一次。哈希去重用的是文件字节级 MD5能抓完全相同的副本抓不到「裁剪过、压缩过」的近重复——近重复得靠感知哈希3000 张的规模用不上先做字节级就够。分辨率分布如果出现大量小于 200×200 的图检测任务里小目标会很难学建议单独拎出来看是否要剔除或放大。2.3 划分训练/验证集时的分层抽样四类数据如果直接random.shuffle再切 8:2小类别可能被切得更少。正确做法是按类别分层抽样保证每类在验证集里的比例和全集一致。import random from sklearn.model_selection import train_test_split samples [] # [(路径, 类别), ...] for sub in root.iterdir(): if sub.is_dir(): for f in sub.rglob(*): if f.suffix.lower() in img_ext: samples.append((str(f), sub.name)) paths [s[0] for s in samples] labels [s[1] for s in samples] train_p, val_p, train_y, val_y train_test_split( paths, labels, test_size0.2, stratifylabels, random_state42 ) print(训练集:, Counter(train_y)) print(验证集:, Counter(val_y))stratifylabels是关键参数它保证切分后每类比例一致random_state42固定随机种子方便复现。切完打印两边的类别计数如果验证集里某类只剩个位数说明该类总量本来就少得回头考虑数据增强或调整test_size。3. 从标注到可训练张量分类与检测两条流水线怎么搭数据验收干净了接下来是把它喂进模型。这份数据集最常见的两种用法是图像分类整图归一类和目标检测框出每个垃圾实例。两条流水线的预处理逻辑差别不小选错方向后面全是返工。3.1 分类流水线Dataset 与增强策略分类任务最简单按文件夹读图、统一尺寸、归一化即可。增强策略上垃圾分类场景有个特点颜色和纹理是强特征比如塑料瓶的透明感、果皮的褐色所以颜色抖动要克制别把关键线索抖没了。import torch from torch.utils.data import Dataset, DataLoader from torchvision import transforms from PIL import Image class GarbageCls(Dataset): def __init__(self, items, transformNone): self.items items # [(路径, 类别名), ...] self.transform transform self.class_to_idx {c: i for i, c in enumerate(sorted({x[1] for x in items}))} def __len__(self): return len(self.items) def __getitem__(self, idx): path, cls self.items[idx] img Image.open(path).convert(RGB) if self.transform: img self.transform(img) return img, self.class_to_idx[cls] train_tf transforms.Compose([ transforms.Resize((224, 224)), transforms.RandomHorizontalFlip(p0.5), transforms.ColorJitter(brightness0.2, contrast0.2, saturation0.1), # 饱和度抖动压低 transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]), ])ColorJitter里saturation0.1是刻意压低的因为垃圾分类里颜色区分度很高抖太狠等于人为制造混淆。Normalize用的是 ImageNet 统计量配合预训练权重时必须这么设否则特征分布对不上。class_to_idx用sorted保证类别索引稳定避免不同机器上跑出不同的标签映射。3.2 检测流水线标注解析与坐标归一化如果标注是 XMLVOC 格式或 JSONCOCO 格式检测任务要先把框解析出来再转成模型要的归一化中心点格式。这一步最容易翻车的是坐标越界和宽高为 0。import xml.etree.ElementTree as ET def parse_voc(xml_path, img_w, img_h): tree ET.parse(xml_path) boxes [] for obj in tree.findall(object): name obj.find(name).text.strip() bnd obj.find(bndbox) x1 float(bnd.find(xmin).text) y1 float(bnd.find(ymin).text) x2 float(bnd.find(xmax).text) y2 float(bnd.find(ymax).text) # 裁剪到图像边界内防止越界框 x1, x2 max(0, x1), min(img_w, x2) y1, y2 max(0, y1), min(img_h, y2) if x2 - x1 2 or y2 - y1 2: # 过滤极小框 continue cx (x1 x2) / 2 / img_w cy (y1 y2) / 2 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h boxes.append((name, cx, cy, w, h)) return boxesmax(0, x1)和min(img_w, x2)这两行是后悔药标注工具里手抖拖出边界的框很常见不裁剪的话归一化后会出现负坐标或大于 1 的值训练时 loss 直接炸。x2 - x1 2过滤掉宽高不足 2 像素的框这类框在缩放后基本消失留着只会干扰回归。解析完记得统计每类框的数量如果某类框数远少于图片数说明该类很多图是「无目标」的检测任务里要当负样本处理。3.3 类别不平衡的加权与采样取舍四类均分是理想情况实际常有偏差。两种处理方式损失函数加权或者重采样。加权改动小、不丢数据我一般优先用它。from collections import Counter import torch counts Counter(train_y) total sum(counts.values()) # 类别权重与频次成反比频次越低权重越高 weights {c: total / (len(counts) * n) for c, n in counts.items()} class_weights torch.tensor([weights[c] for c in sorted(weights)], dtypetorch.float32) criterion torch.nn.CrossEntropyLoss(weightclass_weights)total / (len(counts) * n)是标准的逆频次加权len(counts)是类别数。权重算出来如果某类超过 3说明该类样本实在太少光靠加权可能过拟合得配合过采样或额外采集。重采样WeightedRandomSampler适合类别差距极大的场景但会改变每个 epoch 的样本分布调试时不容易判断是模型问题还是采样问题新手建议先用加权。4. 训练与评估3000 张规模下的参数设定和指标解读数据流水线搭好训练本身反而不复杂。3000 张的规模决定了几个关键选择必须用预训练权重、epoch 不用太多、学习率要小。这一章把参数怎么定、指标怎么看讲透。4.1 迁移学习下的学习率与 epoch 设定从零训练 3000 张四分类大概率欠拟合或过拟合二选一。用 ImageNet 预训练的 ResNet18 或 MobileNetV3冻结主干先训分类头再解冻微调是这类规模的标准打法。import torchvision.models as models import torch.nn as nn import torch.optim as optim model models.resnet18(weightsmodels.ResNet18_Weights.IMAGENET1K_V1) for p in model.parameters(): p.requires_grad False # 先冻结主干 model.fc nn.Linear(model.fc.in_features, 4) # 四类 optimizer optim.Adam(model.fc.parameters(), lr1e-3) # 只训分类头学习率可大些 # 第二阶段解冻后整体学习率降到 1e-4 量级第一阶段只训fc层lr1e-3没问题因为参数量小。跑 5 个 epoch 左右验证集准确率就会趋稳。第二阶段解冻全部参数学习率必须降到1e-4甚至1e-5否则预训练特征会被破坏。epoch 总数控制在 20 到 30配合早停验证 loss 连续 5 轮不降就停3000 张跑下来单卡十几分钟的事。4.2 混淆矩阵比准确率更能说明问题四分类任务里总体准确率 85% 可能掩盖了某一类几乎全错。评估必须看混淆矩阵尤其关注「可回收物 vs 其他垃圾」「厨余 vs 其他」这两组容易混的。from sklearn.metrics import confusion_matrix, classification_report import numpy as np model.eval() all_preds, all_labels [], [] with torch.no_grad(): for imgs, labels in val_loader: preds model(imgs).argmax(dim1) all_preds.extend(preds.cpu().numpy()) all_labels.extend(labels.numpy()) cm confusion_matrix(all_labels, all_preds) print(cm) print(classification_report(all_labels, all_preds, target_namessorted(class_to_idx)))classification_report里的f1-score是重点某类 recall 低说明漏检多precision 低说明误判多。混淆矩阵对角线外的数值直接告诉你哪两类在互相污染。如果「可回收物」大量被判成「其他垃圾」八成是训练集里可回收物的拍摄角度太单一模型没学到泛化特征这时候补数据比调参有用。4.3 验证集指标虚高的三种典型来源第一种是前面说的重复样本跨集泄漏训练集和验证集有同一张图指标自然好看。第二种是验证集太小3000 张切 20% 只有 600 张四类均分每类 150 张波动大单次结果不可信建议做 5 折交叉验证取均值。第三种是增强用在了验证集上——验证集的 transform 只能有 Resize、ToTensor、Normalize绝不能带随机翻转和颜色抖动否则每次评估结果都不一样等于在噪声上做判断。这三种来源我都踩过尤其是第三种早期图省事复用了训练 transform调了两天才发现是评估流程的锅。5. 避坑清单标注、划分、训练里最容易翻车的五件事这一章全是踩坑记录每条按「现象 → 原因 → 解决」写照着对号入座能省不少时间。现象一训练 loss 正常下降验证准确率卡在 25% 不动。原因四分类随机猜就是 25%说明模型根本没学到东西最常见的是标签映射错位——class_to_idx在训练和验证时用了不同的排序或者 DataLoader 的shuffle把标签和图片对错了。解决固定一份class_to_idx存成 JSON训练、验证、推理全部读同一份切分后抽 10 张图人工核对图片和标签是否对应。现象二检测任务里大量框的宽高归一化后接近 0。原因原始标注用的是绝对坐标但解析时误把已经归一化的坐标又除了一次图像尺寸或者图像尺寸读的是缩略图尺寸而非原图尺寸。解决解析前先Image.open(path).size拿真实宽高打印几个框的原始坐标和归一化结果对照宽高小于 0.01 的直接过滤并记录数量。现象三某一类在混淆矩阵里几乎全被判成另一类。原因这两类在视觉上确实接近比如某些塑料制品既像可回收又像其他垃圾或者该类样本的拍摄背景高度一致模型学的是背景不是物体。解决先看该类样本的图片如果背景单一做背景替换或裁剪增强如果确实视觉接近考虑合并类别或引入更细的特征比如材质标注。现象四训练时 GPU 显存溢出但 batch size 已经设得很小。原因检测任务里图片分辨率没统一某批图特别大或者num_workers开太多导致每个 worker 都缓存了一份数据。解决在 Dataset 里强制Resize到固定尺寸num_workers从 2 开始试pin_memoryTrue配合 GPU 训练能提速但会占额外内存显存紧张时关掉。现象五换一台机器复现结果差很多。原因随机种子没固定全——random、numpy、torch三家的种子都要设DataLoader的worker_init_fn也要设否则多 worker 下的增强随机性不可复现。解决写一个set_seed(42)函数在训练脚本开头调用覆盖三家库DataLoader传generatortorch.Generator().manual_seed(42)。提示这五条里标签映射错位和验证集增强泄漏是最隐蔽的因为它们不会报错只会让指标「看起来还行」或「莫名其妙」。每次新数据集上手我都会先跑一个 10 张图的小批量过拟合测试——如果模型连 10 张图都记不住问题一定在数据管道不在模型。6. 把 3000 张用出 3 万张的效果增强、半监督与边界验证3000 张的天花板是明确的但通过合理的增强和训练策略实际效果能往上顶一截。这一章讲三个具体技巧都是我在小数据集上反复验证过的。第一个技巧是「针对性增强」而非「通用增强」。垃圾分类的强特征是形状和材质纹理所以随机裁剪RandomResizedCropscale 设 0.7 到 1.0比随机旋转更有用因为旋转会破坏「瓶子立着」这类先验。翻转可以用但垂直翻转要慎用——垃圾桶里的东西上下颠倒不符合真实拍摄分布。我一般会做一组消融只翻转、只裁剪、两者都上看验证集 f1 哪个高别凭感觉堆增强。第二个技巧是用这份标注数据做「种子」配合半监督扩量。具体做法是先用 3000 张训一个还不错的教师模型然后对未标注的现场图片跑推理挑置信度高于 0.9 的伪标签加入训练集迭代两到三轮。这里的关键是置信度阈值不能太低0.7 以下引入的噪声会把模型带偏。伪标签数据要单独统计来源评估时验证集必须始终是纯人工标注的那部分否则指标不可信。第三个技巧是边界验证——专门构造一批「难例」来测模型边界。比如把可回收物放在厨余垃圾堆里拍、把标签被遮挡的瓶子拍进去、用不同光照条件拍同一类物体。这批图不用多每类二三十张但能暴露模型在真实场景下的短板。我习惯在训练完成后固定跑一遍这批难例记录每类的通过率作为下一轮数据采集的方向。策略数据量变化预期收益主要风险针对性增强不变验证 f1 提升 3~8 个点增强过强导致欠拟合半监督伪标签扩 2~3 倍泛化能力提升明显阈值过低引入噪声难例边界验证不变暴露真实短板难例构造偏差最后说个习惯。从那以后我每次拿到标注数据集不管多急都强制走一遍「统计分布 → 查重查损 → 小批量过拟合 → 混淆矩阵」这四步哪怕只花半小时。这四步能挡掉八成后期调参时根本想不到的玄学问题。这份四类 3000 张的数据集规模适中、类别清晰正好适合把这套流程完整跑一遍跑通了再往自己的真实场景上迁移比一上来就闷头训大模型靠谱得多。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

AI赋能集成电路教育:从知识切片到数字化平台建设路径

AI赋能集成电路教育:从知识切片到数字化平台建设路径

简介:《AI赋能集成电路教育数字化发展白皮书(1.0版)》由北京邮电大学集成电路学院联合教务处、研究生院、国家卓越工程师学院等共同撰写,聚焦智能时代集成电路教育的数字化转型与AI赋能路径,面向高校教育工作者、产业研…

📅 2026/10/25 1:44:08
还在对着静态桌面发呆?DyberPet 5 分钟装好,让屏幕右下角替你盯梢

还在对着静态桌面发呆?DyberPet 5 分钟装好,让屏幕右下角替你盯梢

还在对着静态桌面发呆?DyberPet 5 分钟装好,让屏幕右下角替你盯梢 【免费下载链接】DyberPet Desktop Cyber Pet Framework based on PySide6 项目地址: https://gitcode.com/GitHub_Trending/dy/DyberPet 倒计时跳到 00:00,番茄钟&qu…

📅 2026/10/25 1:44:08
【基于Qt5仿音乐播放器(五)】——数据持久化

【基于Qt5仿音乐播放器(五)】——数据持久化

【基于Qt5仿音乐播放器(五)】——数据持久化1. 数据库初始化2. 歌曲信息写入数据库3. 从数据库中读取支持播放相关功能之后,每次在验证功能时都需要从磁盘中加载歌曲文件,非常的麻烦。而且之前收藏的喜欢歌曲以及播放记录在程序关…

📅 2026/10/25 1:44:08
MORE NEWS

更多资讯

📰

使用srvany.exe将普通程序转为Windows服务的完整指南

1. 为什么需要srvany.exe创建Windows服务在Windows系统中,许多后台程序需要以服务形式运行才能实现开机自启、崩溃重启等关键功能。但并非所有程序都原生支持服务化运行,这时候srvany.exe就派上了用场。srvany是Windows Server Resource Kit工具包中的一…

📰

Mac软件卸载全指南:从基础到深度清理

1. Mac软件卸载的常见误区与正确认知作为一位使用Mac超过十年的老用户,我见过太多人用错误的方式卸载软件。最常见的就是直接把应用图标拖到废纸篓——这种方式看似简单,但实际上只删除了主程序文件,留下了大量系统垃圾。macOS的应用程序采用…

📰

二叉树数据结构:原理、实现与应用全解析

1. 二叉树的基本概念与特性二叉树是每个节点最多只有两个子节点的树形数据结构,这种结构在计算机科学中有着广泛的应用场景。从操作系统内核到数据库索引,从编译器语法分析到游戏场景管理,二叉树的身影无处不在。1.1 二叉树的数学定义严格来说…

📰

企业知识管理工具进化:从IMA到Pandawiki的实践指南

1. 为什么说"ima已死"?企业知识管理工具的迭代逻辑2015年前后,ima作为早期企业知识库解决方案的代表,确实解决了不少企业的文档集中管理需求。但站在2024年的视角回看,这套系统存在三个致命伤:首先是架构层面…

📰

Transformer代码包实战解析:英德翻译与模型训练

简介:AISTransformer数据代码详解是一份聚焦人工智能与机器学习数据预处理的源码型资源,定位为软件/插件类工具,面向算法工程师、数据工程师以及希望掌握数据清洗、特征工程与格式转换的开发者,核心目标是提升数据准备阶段的效率与…

📰

OpenCV 4.5.5工业部署指南:DNN一致性、编译避坑与静态SDK封装

简介:本资源为OpenCV 4.5.5官方版本预编译完成的C动态库分发包,面向计算机视觉初学者、算法工程师及嵌入式开发人员,有效解决手动编译OpenCV耗时长、环境依赖复杂、易出错等痛点,开箱即用,显著降低项目集成门槛。压缩包…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬