尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

基于深度学习的Python垃圾分类系统:从数据集到Web部署全流程解析

发布时间:2026/8/31 22:48:20

资讯中心
01
ARTICLE

基于深度学习的Python垃圾分类系统:从数据集到Web部署全流程解析

基于深度学习的Python垃圾分类系统:从数据集到Web部署全流程解析
简介本资源是一套面向人工智能初学者与计算机专业学生的深度学习实践项目聚焦垃圾分类这一典型图像识别应用场景提供从数据准备、模型训练到系统集成的完整Python实现方案。资源共2000个文件含1986张JPG格式垃圾图片覆盖可回收物、有害垃圾等多类别、8个核心PY源码文件涵盖CNN模型构建、数据集划分、前后端交互及五大功能模块逻辑、4个DOCX文档含系统设计报告、需求规格说明书、测试方案及可行性研究报告压缩包大小为44.31MB。已有516人下载学习适合开展课程设计、毕业设计或AI应用开发实训。读者可直接复现注册登录、智能识别、分类查询、数据划分与白盒测试全流程获得结构清晰的工程化代码框架、详实的文档支撑及可扩展的模型训练基础显著降低深度学习落地门槛。 我这两年帮人做过好几个毕业设计和技术项目其中一个就是基于深度学习的Python垃圾分类系统这个方向的搜索量一直很大说明很多人都在做。但说实话市面上的源码和教程有个通病——给你一堆代码文件注释也写了结果一跑就报错报错还不给原因。所以这篇文章我打算换个思路不贴完整源码而是把我从数据集处理、模型选型到Web展示的整个过程拆开讲每个环节为什么这么做、踩了哪些坑全部交代清楚。1. 垃圾分类系统要解决的到底是什么问题1.1 它不是给图片分类那么简单很多同学第一次拿到这个题目第一反应就是不就是图像分类吗我用CNN跑一遍Imagenet预训练模型精度能到95%完事了。这个理解方向没错但实际操作起来会发现垃圾分类和常规的图像分类有明显区别。常规分类任务比如猫狗识别、花鸟识别类别之间的视觉差异是很明显的。猫就是猫狗就是狗特征边界相对清晰。而垃圾分类常见的几大类——可回收垃圾、厨余垃圾、有害垃圾、其他垃圾——这里面每类包含的物品五花八门。比如可回收垃圾里既有矿泉水瓶也有纸箱还有旧衣服它们的颜色、纹理、形状差异非常大。而其他垃圾里的烟头、陶瓷碎片、脏纸巾又和某些可回收垃圾在视觉上有重合。所以这个系统真正的难点不在模型结构而在类别定义和数据多样性。你得先想清楚是做成四分类四类垃圾还是几十分类具体物品如纸板、玻璃、金属、塑料等这两条路的技术方案差别很大。1.2 我最终采用的方案架构我选择的方案是细粒度物品识别 高层归类映射。第一层模型识别出具体物品比如玻璃瓶报纸香蕉皮废电池等第二层通过建立物品到四分类的映射表自动归类到可回收、厨余、有害、其他。这样做的好处有两个一是用户看到这是玻璃瓶比这是可回收垃圾更有信任感体验更好二是细粒度的分类任务模型能学到更有区分度的特征后续如果投放区域更换了垃圾分类标准比如某些城市分干湿垃圾只需改映射表不用重新训练模型。整体技术链路就是图片输入 - PyTorch读取并预处理 - 深度学习模型推理 - 输出物品类别编码 - 查映射表得到垃圾分类结果 - 展示到前端界面。这个链路简单清晰非常适合做毕业设计或者个人项目展示。下面我把每一环的关键细节展开讲。2. 数据集准备这一环决定了你后面所有工作的上限2.1 别自己手动收集图片公开数据集完全够用我第一次做这个项目的时候天真地想自己从网上爬图片搞了三天图片量不到500张质量还参差不齐。后来学乖了直接上公开数据集。目前垃圾分类领域比较常用的公开数据集有这几个数据集规模类别数特点Garbage Classification约2.5万张6类纸、玻璃、金属、塑料、纸板、垃圾图片比较规整适合入门Huawei Garbage Classification约2万张40类细粒度类别接近真实使用场景TrashNet约2500张6类规模小适合快速验证Kaggle垃圾分类数据集约2万张4大类直接按四分类划分如果你做的是四分类系统建议优先选40类细粒度数据集然后自己建映射。因为直接用4分类数据集训练模型见过的东西太少推广到新场景时容易误判。而用40个类别的数据训练模型对物品本身的理解更深入再映射到四分类时鲁棒性更强。2.2 标注质量检查最容易忽略的一步下载完公开数据集我强烈建议你务必做一次数据分布检查。怎么检查写个Python脚本统计每个文件夹下图片的数量、尺寸分布、是否有损坏文件。我遇到过最坑的情况是某个纸板子类目下混进来了几十张塑料瓶的图片标注噪声直接带偏了模型。还有的图片分辨率是1920x1080有的却是256x256如果统一resize到固定尺寸低分辨率图片的信息可能不够用。动手之前先画个分布直方图看每个类别的样本数是否均衡。垃圾分类数据集往往严重不均衡——其他垃圾可能占一半有害垃圾只有几百张。这种数据扔进去训练模型会偏向样本多的类别。处理方法很简单但效果显著欠采样对样本多的类别随机抽取一部分参与训练重采样对样本少的类别在DataLoader里提高采样概率损失函数加权给样本少的类别更高的loss权重。我实际用下来最省事的是给损失函数加权重就是按类别样本数的倒数归一化不需要额外生成图片文件。这个思路代码量小而且效果稳定。2.3 数据增强策略不要盲目堆一堆操作垃圾分类图片和一般的自然图像不同背景相对简单很多是纯色背景下的物品特写。数据增强主要解决两个问题一是防止过拟合二是模拟真实场景中的光照和角度变化。我的一组增强配置如下from torchvision import transforms train_transform transforms.Compose([ transforms.RandomResizedCrop(size(224, 224), scale(0.7, 1.0)), transforms.RandomHorizontalFlip(p0.5), transforms.RandomRotation(degrees15), transforms.ColorJitter(brightness0.3, contrast0.3, saturation0.3, hue0.1), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ])注意几个细节RandomResizedCrop的scale参数不要设得太小比如不要低于0.5否则会裁剪到物品的局部反而变成难题因为垃圾图片本身不是像文字OCR那样富含上下文信息的。RandomRotation角度不要太大15度以内够了。垃圾图片中有些物品如玻璃瓶旋转后类别不变但旋转90度可能导致关键特征丢失比如瓶身标签。ColorJitter的光照扰动很有用因为实际场景中拍照光线差异很大但这个参数也别过度否则模型会忽略颜色这个重要特征。验证集和测试集不要做任何随机增强只用Resize(256) - CenterCrop(224) - Normalize保证评估结果稳定可复现。3. 模型选型与训练策略别迷信越深越好3.1 为什么我选择了迁移学习而不是从头训练一个很现实的问题垃圾分类系统属于中小数据规模的图像分类任务。哪怕是公开数据集规模也就是2~3万张。用从头训练的深度CNN比如ResNet50去学参数量好几千万这点数据量完全不够用训练只会严重过拟合——train_acc能到99%val_acc却卡在70%。所以我的建议是用ImageNet预训练权重做迁移学习。这些预训练权重已经学到了泛化的视觉特征比如边缘、纹理、形状、部分语义我们只需要在它的基础上微调让它适应垃圾分类这个特定任务。在PyTorch里这一步非常简单import torchvision.models as models # 以MobileNetV3-Large为例 model models.mobilenet_v3_large(pretrainedTrue) # 替换分类头 model.classifier[3] torch.nn.Linear(1280, num_classes)注意不同版本的预训练权重信息来源不同PyTorch现在推荐使用weightsDEFAULT显式声明比如model models.mobilenet_v3_large(weightsmodels.MobileNet_V3_Large_Weights.DEFAULT)3.2 几类主流模型的实测对比我在这套系统上分别跑过ResNet50、MobileNetV3-Large、EfficientNet-B3说说实际感受模型参数量单张推理耗时GPU验证集准确率模型文件大小ResNet50~25.6M约10ms92.3%~98MBMobileNetV3-Large~5.4M约5ms91.8%~22MBEfficientNet-B3~12M约8ms93.1%~45MB从这个结果能明显看出来模型性能并不是和深度严格成正比。ResNet50和MobileNetV3准确率几乎一样但MobileNet体积只有ResNet的四分之一推理速度更快。如果你的系统要部署到树莓派、嵌入式设备或者Web服务上MobileNet系列是性价比之选。如果追求极致精度EfficientNet-B3略高一筹代价是训练和推理都更慢。我的最终选择是MobileNetV3-Large原因有三体积小、速度快、准确率足够高而且它内置了Squeeze-and-Excitation注意力模块对区分看起来很像的垃圾品种有帮助。3.3 训练超参数与优化器选择训练这一个环节我踩过不少坑最重要的一条经验是先冻结骨干网络只训练分类头等loss降下来再解冻全模型微调。第一次做的时候我直接把整个模型扔进去训learning_rate设为0.001结果损失的下降曲线乱七八糟到后期甚至发散。后来按照下面这套参数效果就稳定了阶段一冻结骨干只训分类头优化器AdamW学习率0.001批大小batch size64训练轮数5轮阶段二解冻全部参数微调优化器AdamW学习率0.0001配合CosineAnnealingLR余弦退火批大小64训练轮数15~20轮为什么用AdamW而不是SGDAdamW自带权重衰减正则化效果比Adam更好配合余弦退火可以让学习率在后半段平缓降低避免在loss最小值附近震荡。训练过程中还建议加早停策略early stopping如果连续4~5个epoch验证集准确率没有提升就停止训练并恢复最优模型。PyTorch实现不复杂核心逻辑如下best_acc 0.0 patience 0 for epoch in range(num_epochs): train_one_epoch(...) val_acc evaluate(...) if val_acc best_acc: best_acc val_acc torch.save(model.state_dict(), best_model.pth) patience 0 else: patience 1 if patience 5: break这样既能省时间又能确保保存的是验证集上表现最好的那版权重而不是最后一个epoch的权重。4. 核心代码模块拆解从加载数据到训练出模型4.1 自定义Dataset读取文件夹即标签数据集我按ImageFolder的目录结构组织data/ train/ glass/ paper/ metal/ plastic/ cardboard/ trash/ val/ glass/ paper/ ...如果直接用torchvision.datasets.ImageFolder标签会自动按ASCII排序生成很方便。但我需要的是40类细粒度映射到4大类所以通常会自己写一个GarbageDataset继承torch.utils.data.Dataset。import os from PIL import Image from torch.utils.data import Dataset import numpy as np class GarbageDataset(Dataset): def __init__(self, root_dir, class_to_idx, mapping, transformNone): self.root_dir root_dir self.transform transform self.mapping mapping # 到四位分类的映射 self.samples [] for cls_name in class_to_idx.keys(): cls_dir os.path.join(root_dir, cls_name) for fname in os.listdir(cls_dir): if fname.lower().endswith((.jpg, .jpeg, .png)): self.samples.append((os.path.join(cls_dir, fname), class_to_idx[cls_name])) def __len__(self): return len(self.samples) def __getitem__(self, idx): path, label self.samples[idx] image Image.open(path).convert(RGB) if self.transform: image self.transform(image) return image, label这里有个容易踩的坑Image.open不会立即读取图片内容它是惰性的执行到image Image.open(path)这一步时文件可能还没真正加载到内存。如果后续直接对image做np.array(image)或者transforms操作由于文件句柄已经关闭可能会报OSError: image file is truncated。所以务必加一个.convert(RGB)这会强制把图片完整加载进内存也能统一通道数。4.2 训练循环一个不完美但够用的版本核心训练循环的代码逻辑很简单三句话就能说清取数据、算loss、反向传播。真正体现功力的地方在于IO效率和信息记录。DataLoader里的num_workers参数我实测在Windows上设成0最稳定设大了会报BrokenPipeError在Linux服务器上设成4或8都能明显提速。如果训练数据很大建议先把图片预处理成224分辨率的副本训练时直接加载否则每次epoch都做一次resize白白吃掉大量CPU时间。记录信息这块我用的是tensorboard 本地日志双保险。在训练循环里把每一轮的loss、acc、lr都存下来with open(train_log.txt, a) as f: f.write(fepoch {epoch1}: loss{avg_loss:.4f}, acc{avg_acc:.4f}, val_acc{val_acc:.4f}, lr{current_lr:.6f}\n)这行简单操作在后面调参时帮了大忙。当你同时跑了三组实验用grep对比日志里的val_acc曲线很快就能分辨哪组参数值得继续调哪组直接放弃。4.3 映射表细粒度类别向四大类的转换模型输出的40类编码到四分类的映射我用一个Python字典搞定mapping { glass_bottle: 0, glass_cup: 0, glass_jar: 0, newspaper: 1, cardboard: 1, magazine: 1, banana_peel: 2, apple_core: 2, food_waste: 2, battery: 3, medicine: 3, paint: 3, }映射关系要单独维护成一个JSON文件不要写在代码里。因为垃圾分类标准是各地政府定的你今天的项目在A市部署明天可能要在B市上线只要改JSON文件整个系统的分类规则就跟着变了代码一行都不用动。这个设计在被老师验收时也是一个加分项。5. 训练排障实录我踩过的三个典型坑5.1 GPU显存不足不是你想的那样我用的是笔记本上的GTX 16504GB显存第一次训练ResNet50batch_size设成64一跑就CUDA out of memory。我当时第一反应是减小batch size从64减到32还是爆减到16勉强能跑但训练速度慢得离谱。后来查了资料才明白问题出在我同时开着PyCharm、浏览器、微信等一堆程序占用大量系统内存而GPU在batch_size计算时会把中间激活值缓存在显存里系统内存不够时就会出问题。解决方案关掉不必要的图形界面应用把训练脚本改成python train.py命令行运行使用torch.cuda.empty_cache()清理显存碎片注意这个函数只清空缓存不释放已分配的张量别指望它解决真正的OOM。如果还是不够就把batch size降到8同时把图像输入尺寸从224降到192用scale动态调整。反正最终验证集准确率下降幅度在1%以内总比跑不起来强。5.2 验证集准确率上不去但训练集准确率接近100%这是非常典型的过拟合信号。出现这个情况我一开始怀疑是模型太深了后来一步步排查才发现根本不是。第一先检查数据划分。我用的是随机划分但这个随机其实有个隐患同一个类别的图片可能在划分前被全部排到了一起。解决方案是使用sklearn.model_selection.train_test_split在文件夹级别做划分确保每种类别图片在训练集和验证集里都按比例出现。第二加Dropout。MobileNetV3的classifier层里自带Dropout默认概率是0.2我调到0.5后验证集准确率提升了大约2个百分点。别小看这一层它直接决定模型有没有死记硬背训练样本的特征。第三最有效的还是数据增强里的RandomErasing或CutMix随机擦除图片的一部分强迫模型关注整体特征而不是某一小块区域。transform transforms.Compose([ # ... 之前的增强 transforms.RandomErasing(p0.5, scale(0.02, 0.15)), ])注意RandomErasing必须在ToTensor之后用因为它操作的是张量。5.3 模型预测时总是把塑料瓶识别成玻璃瓶这个问题有意思验证集准确率很高但实际测试时却翻了车。我的排查思路是先看训练集里塑料瓶和玻璃瓶的样本数发现玻璃瓶明显多于塑料瓶。再看了下样本图片很多塑料瓶是透明的和玻璃瓶在视觉上几乎没法区别尤其是有光照反射的时候。最终解决是用背景增强让模型不再只靠透明圆柱形来判断因为这两个特征在两类中都存在。我在数据增强里加了RandomGrayscale(p0.1)偶尔把彩色图片转灰度模型被迫学除了颜色以外的形状、纹理特征。虽然准确率提升不算特别大但误判率确实明显下降了。这件事给我的启发是模型表现差的时候先看看数据里到底有哪些区分性线索再决定是改模型还是改数据。6. 推理部署与Web展示从能跑到能用6.1 Flask后端搭建把模型封装成API训练好的模型最终要通过一个接口暴露给前端使用。我用Flask写了一个轻量级的推理服务代码量不大from flask import Flask, request, jsonify from PIL import Image import torch import torchvision.transforms as transforms import torchvision.models as models import io app Flask(__name__) # 加载模型 model models.mobilenet_v3_large(weightsNone) model.classifier[3] torch.nn.Linear(1280, 40) model.load_state_dict(torch.load(best_model_garbage.pth, map_locationcpu)) model.eval() preprocess transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) app.route(/predict, methods[POST]) def predict(): file request.files[image] image Image.open(file.stream).convert(RGB) image_tensor preprocess(image).unsqueeze(0) with torch.no_grad(): outputs model(image_tensor) probs torch.softmax(outputs, dim1) confidence, idx torch.max(probs, dim1) # idx - 类别名 - 映射成四分类 result {class_id: idx.item(), confidence: round(confidence.item(), 4)} return jsonify(result) if __name__ __main__: app.run(host0.0.0.0, port5000)有几个关键点map_locationcpu是为了在无GPU环境下也能加载模型不然换到没有CUDA的服务器上会报错每次推理时要加上torch.no_grad()它告诉PyTorch不需要计算梯度能大幅降低显存消耗和推理耗时模型的eval()模式不能漏漏了的话Dropout和BatchNorm的行为会和训练时一样导致推理结果不稳定。6.2 前端页面一张图片、一次点击、一个结果前端我写了一个单页面HTML样式就用纯色背景加卡片式布局通过fetch上传图片到Flask后端然后显示返回的结果和置信度。input typefile idimageInput acceptimage/* button onclickuploadImage()识别/button div idresult/divasync function uploadImage() { const fileInput document.getElementById(imageInput); const formData new FormData(); formData.append(image, fileInput.files[0]); const response await fetch(/predict, { method: POST, body: formData }); const data await response.json(); document.getElementById(result).innerText 类别ID: data.class_id 置信度: data.confidence; }如果想让这个系统看起来更高级一点可以在前端调用摄像头getUserMedia做实时识别但要注意摄像头帧率很高每帧都发到后端推理对服务器压力很大。我采用的方案是前端每2秒取一帧只有画面变化超过阈值才发请求这样既保持实时性又不会把服务器打垮。6.3 置信度阈值让系统会说不知道很多人做完分类系统就完了用户传一张不相关的图片比如一只猫系统也会强行说出一个垃圾类别这就是胡说八道。为了避免这个尴尬场景我在后端的预测逻辑里加了一个置信度判断if confidence 0.6: result {error: 无法识别请拍摄更清晰的物体照片} else: result {class_id: idx.item(), confidence: round(confidence.item(), 4)}这个0.6的阈值不是拍脑袋定的而是我在验证集上算出来的。具体做法是把50张不属于任何类别的图片混进去测试观察模型给出的置信度分布取能让误判率小于5%的阈值。这样系统在遇到未知物体时会诚实地告诉用户我不认识而不是瞎猜。7. 总结一下我从这个项目里沉淀出的几条经验做垃圾分类系统这件事技术栈并不复杂难的是把每个环节做扎实。数据集决定了天花板模型和训练方法决定你能不能接近这个天花板而工程化能力决定你的系统能不能被别人用起来。我个人最大的体会是千万不要跳步。很多同学下载源码第一件事就是跑训练跑通就认为完事了完全不看数据分布、不验证模型的泛化能力最后答辩的时候面对老师的一个问题就懵了。老师随便问一句你的模型为什么选择MobileNetV3而不是ResNet或者训练集和验证集怎么划分的如果没提前做过对比实验根本答不上来。这个系统后续可以扩展的方向也不少比如加入OCR识别包装袋上的文字、加入语音播报提示、部署到小程序端甚至用目标检测算法YOLO系列实现多物品同时识别每次看到一篮子垃圾可以一次性给出各自的分类。不过这些都是后话了先把图像分类这条主线跑通后面加功能自然水到渠成。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。