基于深度学习的垃圾分类系统:从模型训练到部署的完整工程实践

发布时间:2026/9/24 18:05:56
基于深度学习的垃圾分类系统:从模型训练到部署的完整工程实践 简介这份资源是面向高校Python课程学习者与深度学习入门者的垃圾分类系统大作业完整方案基于卷积神经网络实现垃圾图像的自动识别与分类覆盖数据采集、预处理、特征提取、分类输出等完整流程适合作为课程设计、期末大作业或入门实战项目参考。压缩包共134个文件约75.59MB包含20个py源码、13个ipynb实验笔记、12个vue与14个js前端页面、19个png效果图以及部署指南、参考报告、答辩ppt、sqlite3数据库和onnx模型等文档与配置结构完整、模块清晰。项目源码均经本地编译调试可稳定运行评审分达95分以上难度适中内容经助教老师审定。已有89人学习下载读者可据此快速复现系统、理解模型训练与前后端联调思路并直接参考报告与演示文稿完成课程提交。1. 从一份课程大作业说起垃圾分类系统到底难在哪很多人第一次看到「基于深度学习的垃圾分类系统」这个题目第一反应是不就是个图像分类吗拿 ResNet 跑一遍完事。真动手才发现翻车点根本不在模型结构上。垃圾图像本身类间差异极小——一个揉皱的纸巾和一块用过的厨房纸在 224×224 的输入下几乎一模一样而类内差异又极大——同一个「可回收物」标签下矿泉水瓶、纸箱、易拉罐的外观分布完全不同。这才是这个题目真正卡人的地方。这份课程大作业通常包含源码、部署指南、报告 PPT 和全部文档本质上是一个完整的工程闭环数据采集与清洗、模型选型与训练、推理服务封装、前端交互、以及最后的报告呈现。它适合两类人一是正在做 Python 课程设计、需要一套能跑通且能讲清楚的学生二是想用一个小型视觉项目把深度学习从「调包」推进到「部署」的入门工程师。接下来我按实际落地的顺序把这条链路拆开讲。2. 数据与模型选型为什么不用现成数据集直接开跑2.1 垃圾分类数据集的三个现实约束公开的垃圾分类数据集不是没有但直接拿来用通常会遇到三个问题。第一类别定义不统一。有的数据集分四类可回收、厨余、有害、其他有的分六类甚至四十多类而课程报告里往往要求按本地标准来。第二图像来源单一。很多数据集是从电商白底图爬的模型学到的是「白底 居中物体」这个捷径一到真实拍摄的杂乱背景就崩。第三样本不均衡。有害垃圾的样本量通常只有可回收垃圾的十分之一直接训练会让模型倾向于预测多数类。我一般的做法是以公开数据集为底自己补拍 200300 张真实场景图重点补有害垃圾和厨余垃圾。补拍时故意制造背景干扰——放在桌面上、拿在手里、放在垃圾桶旁边各拍几张。这样做的代价是标注工作量增加但换来的泛化能力提升在答辩演示时非常明显。数据划分建议按 7:1.5:1.5 切分训练、验证、测试集并且按「拍摄批次」划分而不是随机划分。如果同一批拍的照片同时出现在训练集和测试集里测试准确率会虚高好几个百分点这是血泪经验。2.2 模型选型MobileNetV3 还是 ResNet18课程大作业的算力预算通常有限要么是实验室的一张消费级显卡要么是 Colab 免费额度。在这个约束下模型选型要在精度和推理速度之间做权衡。模型参数量输入尺寸适合场景注意事项MobileNetV3-Small约 2.5M224×224部署到边缘设备或 CPU 推理精度略低需更多数据增强MobileNetV3-Large约 5.4M224×224平衡精度与速度课程作业首选ResNet18约 11.7M224×224追求精度、显存充足训练慢容易过拟合小数据集EfficientNet-B0约 5.3M224×224精度优先输入分辨率敏感需调参如果只是课程作业我建议从 MobileNetV3-Large 起步。它的预训练权重在 ImageNet 上表现稳定迁移到垃圾分类这种细粒度任务上通常用 3050 个 epoch 就能收敛到一个可接受的水平。ResNet18 不是不能用但在样本量不足一万张的情况下过拟合风险明显更高需要更强的正则化。2.3 用迁移学习跑通第一个 baseline下面这段代码是一个最小可运行的训练脚本基于 PyTorch 和 torchvision假设数据已经按ImageFolder格式组织好。import torch import torch.nn as nn from torchvision import datasets, models, transforms from torch.utils.data import DataLoader # 数据增强训练集用较强的增强验证集只做 resize 和归一化 train_tf transforms.Compose([ transforms.RandomResizedCrop(224, scale(0.7, 1.0)), transforms.RandomHorizontalFlip(), transforms.ColorJitter(0.2, 0.2, 0.2), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) val_tf transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) train_ds datasets.ImageFolder(data/train, transformtrain_tf) val_ds datasets.ImageFolder(data/val, transformval_tf) train_loader DataLoader(train_ds, batch_size32, shuffleTrue, num_workers4) val_loader DataLoader(val_ds, batch_size32, shuffleFalse, num_workers4) # 加载预训练 MobileNetV3-Large替换分类头 model models.mobilenet_v3_large(weightsmodels.MobileNet_V3_Large_Weights.DEFAULT) num_classes len(train_ds.classes) model.classifier[3] nn.Linear(model.classifier[3].in_features, num_classes) model model.cuda() criterion nn.CrossEntropyLoss() optimizer torch.optim.AdamW(model.parameters(), lr1e-3, weight_decay1e-4) scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max30) for epoch in range(30): model.train() for imgs, labels in train_loader: imgs, labels imgs.cuda(), labels.cuda() optimizer.zero_grad() loss criterion(model(imgs), labels) loss.backward() optimizer.step() scheduler.step() # 每个 epoch 后在验证集上评估 model.eval() correct total 0 with torch.no_grad(): for imgs, labels in val_loader: imgs, labels imgs.cuda(), labels.cuda() pred model(imgs).argmax(dim1) correct (pred labels).sum().item() total labels.size(0) print(fepoch {epoch1}, val_acc{correct/total:.4f})逻辑说明这段脚本做了三件事——构建带增强的数据管道、加载预训练模型并替换分类头、用余弦退火学习率跑训练循环。关键参数有三个batch_size32在 8GB 显存下比较稳妥显存不够就降到 16lr1e-3是 AdamW 在迁移学习场景下的常用起点如果 loss 震荡明显可以降到 5e-4T_max30要和总 epoch 数一致否则学习率调度会提前结束。跑完这个 baseline如果验证集准确率卡在 70% 以下先别急着换模型大概率是数据问题——检查一下类别是否均衡、有没有标注错误、训练集和验证集是否来自同一分布。3. 推理服务与前端交互把模型变成能演示的系统3.1 用 FastAPI 封装推理接口课程作业的演示环节老师通常不会看你训练脚本跑得怎么样而是直接打开一个页面上传一张图片看系统能不能给出分类结果。所以推理服务的封装是必须做的。from fastapi import FastAPI, UploadFile, File from PIL import Image import torch, io from torchvision import transforms app FastAPI() model torch.load(best_model.pth, map_locationcpu) model.eval() tf transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) classes [可回收物, 厨余垃圾, 有害垃圾, 其他垃圾] app.post(/predict) async def predict(file: UploadFile File(...)): img Image.open(io.BytesIO(await file.read())).convert(RGB) tensor tf(img).unsqueeze(0) with torch.no_grad(): logits model(tensor) prob torch.softmax(logits, dim1) conf, idx prob.max(dim1) return {class: classes[idx.item()], confidence: round(conf.item(), 4)}逻辑说明接口接收上传的图片做和验证集一致的预处理然后前向推理取最大概率类别。参数上map_locationcpu是为了在没有 GPU 的演示机上也能跑unsqueeze(0)是补上 batch 维度。返回结果里带上置信度演示时可以展示「系统有多确定」比只返回一个类别更有说服力。3.2 前端页面与部署指南的关键步骤前端不需要多复杂一个 HTML 页面加一段 JavaScript 就够了。核心逻辑是用户选图片 → 预览 → 点击按钮 → fetch 调用/predict→ 展示结果。async function predict() { const fileInput document.getElementById(file); const formData new FormData(); formData.append(file, fileInput.files[0]); const res await fetch(/predict, { method: POST, body: formData }); const data await res.json(); document.getElementById(result).innerText 分类结果${data.class}置信度${data.confidence}; }部署指南里最容易漏掉的一步是跨域和静态文件挂载。如果前端和后端不在同一个端口浏览器会拦截请求。最简单的做法是用 FastAPI 的StaticFiles把前端页面挂到同一个服务下这样就不存在跨域问题。pip install fastapi uvicorn python-multipart pillow torch torchvision uvicorn main:app --host 0.0.0.0 --port 8000启动后访问http://localhost:8000就能看到页面。如果部署到服务器上把--host改成0.0.0.0让外部可访问端口按需调整。注意python-multipart这个包必须装否则文件上传接口会直接报错这个坑我踩过不止一次。3.3 报告 PPT 里该放什么、不该放什么课程大作业的 PPT 和工程文档是两回事。PPT 的核心不是展示你调了多少参数而是讲清楚三件事问题定义为什么垃圾分类值得做、技术方案你选了什么模型、为什么、结果验证准确率、混淆矩阵、实际演示截图。我见过太多 PPT 把训练 loss 曲线放了三页但老师最关心的其实是「你的系统和现有方案比好在哪」。所以建议留一页做对比比如你的模型在自建测试集上的准确率和直接用公开数据集训练的模型对比差距在哪里为什么。这一页往往决定了答辩的分数上限。混淆矩阵是必须放的。垃圾分类的混淆矩阵通常会在「厨余垃圾」和「其他垃圾」之间出现明显误判把这个现象解释清楚——比如「因为剩饭剩菜和污染纸巾在视觉上高度相似」——比单纯报一个准确率数字更能体现你对问题的理解。4. 避坑与排查那些让系统跑不起来的细节4.1 现象训练准确率很高但演示时识别全错原因训练集和演示时的输入分布不一致。训练用的是公开数据集的白底图演示时用的是手机拍的杂乱背景图模型没学过这种分布。解决在训练集中混入至少 20% 的真实场景图并且做更强的颜色抖动和随机裁剪增强。4.2 现象推理接口返回 500日志显示缺少 multipart原因FastAPI 处理文件上传依赖python-multipart这个包不会随 FastAPI 自动安装。解决pip install python-multipart然后重启服务。如果用的是 requirements.txt记得把它写进去否则换一台机器部署时又会复现。4.3 现象模型文件加载报错提示缺少某个模块原因保存模型时用了torch.save(model)保存整个模型对象而不是torch.save(model.state_dict())。前者会把模型类的路径也序列化进去换一个目录或换一台机器就找不到类定义。解决训练时只保存state_dict推理时先实例化模型结构再加载权重。这是一个典型的「当时省事、后面翻车」的操作。4.4 现象验证集准确率波动很大每次跑结果都不一样原因小数据集加上随机划分导致验证集本身不具有代表性。另外如果num_workers设置过大而磁盘 IO 跟不上数据加载顺序也会引入额外随机性。解决固定随机种子torch.manual_seed(42)并且用 K 折交叉验证代替单次划分至少跑三次取平均。4.5 现象部署到服务器后第一次推理特别慢原因模型在 CPU 上第一次前向传播时需要做算子初始化加上如果用了torch.load懒加载第一次调用会触发实际加载。解决在服务启动时先跑一次 dummy 推理把初始化开销提前消化掉。这个技巧在演示前特别有用避免老师等半天才出结果。5. 进阶技巧用混淆矩阵反推数据问题最后一章讲一个我反复用到的技巧不要只看准确率把混淆矩阵当成数据诊断工具。训练完模型后在测试集上跑一遍用 sklearn 输出混淆矩阵from sklearn.metrics import confusion_matrix, classification_report import seaborn as sns import matplotlib.pyplot as plt all_preds, all_labels [], [] model.eval() with torch.no_grad(): for imgs, labels in test_loader: preds model(imgs.cuda()).argmax(dim1).cpu() all_preds.extend(preds.tolist()) all_labels.extend(labels.tolist()) cm confusion_matrix(all_labels, all_preds) sns.heatmap(cm, annotTrue, fmtd, xticklabelsclasses, yticklabelsclasses) plt.savefig(confusion_matrix.png) print(classification_report(all_labels, all_preds, target_namesclasses))拿到混淆矩阵后重点看两件事。第一哪两个类别之间的误判最多。如果「厨余垃圾」被大量预测成「其他垃圾」说明这两类的视觉边界在你的数据里不够清晰需要补充区分性更强的样本比如带汤水的厨余 vs 干燥的纸巾。第二看每一类的召回率。如果「有害垃圾」的召回率明显低于其他类说明样本量不足需要针对性补数据而不是调模型。这个技巧的价值在于它把「模型效果不好」这个模糊的问题转化成了「哪两类之间的数据需要补充」这个具体行动。我一般会在训练完第一版模型后先看混淆矩阵再决定第二轮是补数据还是调参。大多数情况下补数据的收益远大于调参。还有一个细节报告 PPT 里的混淆矩阵最好用百分比归一化后的版本而不是原始计数。因为类别不均衡时原始计数会让小类别的误判看起来不明显而归一化后每一类的误判比例一目了然答辩时也更好讲。最后说一个习惯每次训练完把模型文件、混淆矩阵、分类报告、以及当次使用的超参数一起存到一个以日期命名的文件夹里。课程作业往往要反复迭代好几版没有这个习惯过两天就分不清哪个模型是哪个版本了。这个习惯看起来笨但省下来的时间远超那点存储成本。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询