
简介这是一套基于Python与深度学习技术实现的垃圾分类系统高分毕业设计源码适合计算机相关专业学生用于毕业设计、期末大作业或课程设计参考。项目已获老师指导并通过代码结构清晰、注释完整对小白用户尤为友好。资源共6319个文件主要包括1457个py源码文件、1454个pyc编译文件、1182个mo/po多语言文件以及html/js/css前端页面文件其中py为系统核心后端代码html/js/css构成可视化交互界面压缩包总大小约18.98MB目录与依赖环境组织规范便于直接运行和二次开发。目前已有338人学习下载。压缩包内含完整的垃圾分类模型训练代码、基于深度学习的识别预测实现、Web展示界面以及配套依赖环境配置可快速复现系统并掌握数据预处理、模型构建、训练评估与部署的基本流程是理解图像分类技术在环保领域落地应用的便捷学习材料。1. 这是什么东西一个能跑通的垃圾分类模型外加一整套课设源码很多人第一次拿到“基于python与深度学习的垃圾分类系统设计与实现源码高分项目.zip”时以为是某种神秘的高分模版。其实拆开看就是一套完整的图像分类项目用 python 写数据加载和训练流程用深度学习模型对垃圾图片分门别类最后附上可以直接运行的源码和项目文档。它解决的问题很实际——毕业设计或课程设计需要“能演示、能截图、能答上参数”的完整系统。适合正在做课设的学生、想转行 AI 的开发者以及需要一个最小可落地图像分类模板的工程师。拿到手第一件事不是解压看代码而是先想清楚这套系统由哪几块组成、数据和模型从哪里来否则很容易在环境阶段就卡住。2. 先看懂系统是怎么设计的模型选型、数据流与代码结构2.1 为什么选深度学习的图像分类落地方案垃圾分类在算法层面其实是一个典型的图像分类任务输入的是一张拍摄或上传的垃圾图片输出的是可回收物、厨余垃圾、有害垃圾、其他垃圾这粗分四类或者进一步细分到塑料、纸张、玻璃、金属等十几个子类。早期方案有人用传统图像处理比如基于颜色的 HSV 分割、基于形状的轮廓匹配效果极其不稳定——换个光照分类就翻车。深度学习方案的胜出点在于不需要手工设计特征只要数据足够模型自己能学到“易拉罐和玻璃瓶在纹理上的区别”。实际项目中常见的做法是用卷积神经网络CNN做特征提取比如 ResNet、MobileNet、EfficientNet。因为这些预训练模型在 ImageNet 上已经学会了通用特征拿到垃圾分类这种小规模数据集上做迁移学习可以在很少的标注数据下收敛。我在课设项目里一般会选择 ResNet18 或者 MobileNetV2理由是ResNet18 结构简单、参数少CPU 也能跑MobileNetV2 更轻量后面部署到树莓派或者手机端不吃力。如果你的机器有独显换 ResNet50 能提一点准确率但训练时间和显存占用会明显上升。整个数据流可以概括为图片读入 → 统一缩放 → 归一化 → 输入网络 → 得到每类的概率 → 取最大概率对应的类别。这个流程在任何深度学习框架里都是一套标准写法。项目的核心源码其实就是围绕这条数据流展开的如果你手里的源码包里有 train.py、test.py、predict.py 和 dataset.py 这类文件大概率就是按这个思路组织的。2.2 数据从哪里来公开数据集与本地自建数据集的组织方式垃圾分类项目最容易被忽略的是数据。很多源码包自带了少量示例图片但训练一个能看的模型每类最好至少有几百张图。公开数据源里Huawei 的垃圾分类数据集、清华大学开源的中文垃圾分类数据集、Kaggle 上的 trashnet 都可以用。这些数据集的类别定义不一定一致落地前要先把类别映射统一。我一般会把数据集组织成 ImageFolder 标准形式方便 PyTorch 的datasets.ImageFolder直接读取data/ train/ 可回收物/ 1.jpg 2.jpg ... 有害垃圾/ ... val/ ...这种组织方式的好处是你不用自己写解析csv的代码框架会自动根据文件夹名生成类别索引。注意一个坑口是目录名不要用中文。虽然 Windows 和 Linux 下的 Python 3 基本支持中文路径但在 PyTorch 的 DataLoader 多线程加载时偶发报错或乱码很常见浪费你半天时间。我经历的教训是先把中文类别转成英文或拼音目录名比如recyclable、kitchen_waste然后维护一个label_map.json做中英文映射界面显示时再转回中文。如果公开数据集不够一个偷懒但有效的自建数据方法是用手机拍 50 张不同光照下的瓶子再用 OpenCV 做左右翻转、随机旋转、亮度变化扩增到 200 张。扩增代码非常简单但要注意别做无意义的扩增比如水平翻转对“易拉罐”有效对“玻璃瓶”也有效但如果你做的是“区分瓶盖方向”这类任务翻转会破坏语义需要谨慎。2.3 源码里的典型代码结构与关键文件拿到“基于python与深度学习的垃圾分类系统设计与实现源码”这种包先看目录结构不要急着先运行。我见过的课设源码包绝大多数都长这样project/ data/ # 数据集按 train/val 分好 models/ # 网络定义可能有使用的预训练权重 datasets.py # 数据加载逻辑 train.py # 训练入口 test.py # 在测试集上算准确率 predict.py # 单张图片推理 gui.py # 可视化界面有的项目叫 ui.py 或 app.py README.md # 说明文档 requirements.txt # 依赖清单train.py里的核心逻辑通常是三步加载 ImageFolder 数据、定义模型和损失函数、跑训练循环。predict.py负责单张图片的加载、预处理、前向传播和后处理。gui.py用 tkinter 或 PyQt 实现窗口核心就是一个“选择图片 → 显示结果”的回调函数。我建议你把requirements.txt作为第一个阅读文件它能告诉你这个项目依赖哪些版本。如果里面写的是torch1.8这种宽泛约束那么环境安装会比较友好如果锁了torch1.4.0而你的机器是新的 CUDA 环境很可能装不上需要手动调整。3. 把垃圾分类模型跑起来环境搭建与训练配置3.1 用 Python 环境跑通训练的最小步骤不要一上来就装一堆包。先建独立环境再装框架和依赖。常见做法是用 Anaconda 建环境conda create -n garbage python3.8 conda activate garbage pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install numpy opencv-python pillow tqdm代码逻辑是先建一个干净的 Python 3.8 环境防止把系统 Python 搞坏。然后安装 PyTorch 和 torchvision这里指定了cu118的 index-url表示用 CUDA 11.8 对应的预编译包。如果你的笔记本电脑没有 NVIDIA 显卡就把这一行换成 CPU 版pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu参数说明python3.8是兼容性最好的版本PyTorch 官方对 3.8 的支持最稳不要用 3.12 或 3.13 去碰老源码很多项目里的setup.py和旧代码在超新版本上会报错。cu118中的cu代表 CUDA 版本不是任意数字都行要先nvidia-smi看一下驱动支持的 CUDA再挑对应的 PyTorch 包。环境建好后先跑一个最小训练脚本确认数据能正确加载import torch from torchvision import datasets, transforms transform transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) dataset datasets.ImageFolder(data/train, transformtransform) print(类别数, len(dataset.classes)) print(图片数, len(dataset))这段代码的作用是把data/train下的图片统一缩放为224×224转成 Tensor 并归一化。用于 ResNet 的归一化均值方差是 ImageNet 的固定值直接抄就行。如果打印出的图片数是 0大概率是目录结构不对回去把子文件夹放好。3.2 训练参数怎么调batch size、学习率与 epochs训练脚本里最容易调整也最影响效果的是 batch size、学习率和 epochs。我一般先用默认配置把流程跑通再考虑调参。下面是经过整理的一个常见训练循环简化版model resnet18(pretrainedTrue) model.fc nn.Linear(model.fc.in_features, num_classes) criterion nn.CrossEntropyLoss() optimizer torch.optim.Adam(model.parameters(), lr0.001) for epoch in range(epochs): for images, labels in train_loader: outputs model(images) loss criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step()逻辑说明先加载在 ImageNet 上预训练过的 ResNet18把最后一层全连接顺滑替换成自己的类别数。因为特征抽取层已经学好训练时只需要让新的全连接层和最后一组残差块适应垃圾图片就行。CrossEntropyLoss是分类任务的标准损失Adam是主流优化器新手不需要去深究里面的动量公式先跑通再调。参数经验值batch size 在 16 到 32 之间比较稳。显存只有 4G 用 166G 以上用 32。学习率0.001是 Adam 的常见起点如果你换用 SGD学习率通常要设成0.01或0.005。epochs 不要一上来就设 100垃圾分类这种中小规模数据集30 轮以内就能看到过拟合迹象。我习惯每轮跑完后在验证集上算一次准确率只保存最高准确率的权重。3.3 用训练好的权重做单张图片与摄像头识别模型训练完最终落地是“拿一张图丢进去出来一个类别”。写预测脚本时最关键的坑是训练时的预处理和推理时的预处理必须完全一致。很多人训练时用了Resize、Normalize推理时忘记加导致结果全偏。import torch from PIL import Image from torchvision import transforms transform transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) model.load_state_dict(torch.load(best.pth, map_locationcpu)) model.eval() with torch.no_grad(): img Image.open(test.jpg).convert(RGB) input_tensor transform(img).unsqueeze(0) output model(input_tensor) pred output.argmax(dim1).item()逻辑要点model.eval()会关闭 Dropout 和 BatchNorm 的训练状态这能避免推理时结果抖动。torch.no_grad()让 PyTorch 不保存计算图推理速度会快不少内存占用也低。unsqueeze(0)是为了把三维的C×H×W张量变成四维的N×C×H×W因为网络要求输入带 batch 维。摄像头识别是另一个常见演示需求核心就是帧循环。我一般用 OpenCV 打开摄像头每一帧取出来先缩小再送入模型识别的结果绘制在画面上。注意帧率不要要求太高CPU 上每帧处理 0.3 到 0.5 秒是正常的观感会有点卡但演示够用了。如果你的课设要求实时性建议把图像分辨率降到 192×192或者干脆用 MobileNet 替换 ResNet。4. 踩坑与排查新手最容易翻车的 5 个地方4.1 数据集路径中文名导致加载失败现象代码在本地 IDE 里反复横跳dataset datasets.ImageFolder(data/train)时明明存在路径却报FileNotFoundError或解压后运行时读到一半停了。更诡异的是同一个代码换个环境又正常。原因多数是数据集文件夹或图片文件名带中文Windows 的编码和 PyTorch 的 DataLoader 多进程编码冲突。另外备注过一个常见情况有些同学把数据集放在C:\用户\张三\桌面\垃圾分类项目\data\train这样的路径在代码里硬编码换到别的电脑就必然报错。解决把整个项目路径改成纯英文比如D:\garbage_project\data\train把中文类别目录改成英文目录维护一个映射表路径不要写绝对路径统一用相对路径。具体做法是在项目根目录下建一个config.yaml或者直接在train.py顶部用BASE_DIR Path(__file__).parent获取项目根目录再拼数据路径这样无论别人解压到哪里都能跑。4.2 图片尺寸不一致导致训练崩溃现象训练到中途RuntimeError: stack expects each tensor to be equal size或者某个 batch 直接失败提示Expected tensor to be a CPU tensor这类很抽象的信息。看日志会发现前几轮没问题后面换了一批图就崩。原因数据集里有不同宽高比的图片。虽然transforms.Compose里有Resize((224, 224))但如果有些源码用的是transforms.Resize(224)这个操作只会把短边缩放到 224长边保持比例不变最终得到的图片尺寸不一致PyTorch 在组成 batch 时无法堆叠。解决统一用Resize((224, 224))确实能避免尺寸不一致但会拉伸图片造成变形。更好的做法是先用Resize(256)把短边统一再用CenterCrop(224)这样裁剪出来的内容更自然而且尺寸一定是 224。如果你手里的源码是两种预处理混用建议直接改成一个固定的 transform。transform_train transforms.Compose([ transforms.Resize((256, 256)), transforms.CenterCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ])参数说明这里先缩放到 256再中心裁剪到 224是为了保留一定的随机裁切空间也兼容不同尺寸的原图。RandomHorizontalFlip是常用的数据增强对垃圾分类这类方向无关的任务安全。4.3 CUDA 与 PyTorch 版本不匹配导致训练时黑匣子报错现象安装完 torch 后运行torch.cuda.is_available()返回 False或者训练一使用.cuda()就报CUDA runtime error: invalid device function。原因最常见的是 PyTorch 官方包要求的 CUDA 版本和你机器显卡驱动支持的最高版本不一致或者你装了 CPU 版 torch 又幻想能用 GPU。还有一种情况是在一个环境里混装了torch和torchvision的不同版本二者 ABI 不兼容。解决先跑三行命令确认环境python -c import torch; print(torch.__version__) python -c import torch; print(torch.cuda.is_available()) nvidia-smi第一步看 torch 版本第二步看 GPU 可用性第三步看驱动支持的 CUDA 版本。如果第三步显示的比你安装的 PyTorch 对应版本低就去官网换一个更低的cu包。如果第二步是 False而你确认驱动没问题说明装的是 CPU 包卸载重装pip uninstall torch torchvision pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121注意CUDA 版本要匹配不是越高越好。比如你的显卡驱动只支持 CUDA 11.8强行装 cu121 的包程序启动时报错也很麻烦。做课设没有 GPU 就老实跑 CPU垃圾图片量不大ResNet18 在 CPU 上 30 轮也就几小时。4.4 Loss 不下降的常见原因现象loss 一直在 2.3 左右徘徊每轮结束都是同样数值准确率上不去。原因如果你的类别数是四类随机乱猜的损失的 log(4)1.39 附近。loss 卡在 2.3 说明输出概率分布极端通常是学习率太大导致梯度震荡或者数据归一化有问题。更常见的一个低级错误是model.train()和model.eval()状态没切换训练时使用了 BatchNorm 的训练状态测试时效果全无。解决检查学习率Adam直接从0.001降到0.0005试试检查输入图片是否真的做了归一化很多项目中忘了调transforms.Normalize像素范围还在 0 到 255 之间网络前端会被撑坏检查数据打乱DataLoader里设置shuffleTrue否则每轮都是相同批次顺序优化方向单调。修复后再训练loss 一般会在前 5 轮有肉眼可见下降如果还没有就把模型换小从 ResNet18 换成两层卷积的自定义小网络定位问题是不是在数据。4.5 摄像头识别卡顿与 UI 线程卡死现象用 PyQt 或 tkinter 写界面点击“打开摄像头”后窗口直接无响应过几秒后弹出“Not Responding”。或者摄像头画面实时预览流畅但一按识别按钮画面冻结。原因这是典型的把耗时操作放在 UI 主线程的问题。PyQt 的窗口消息循环被模型前向推理阻塞界面自然卡死。OpenCV 摄像头视频流本身是独立线程推理占 CPU 太高会导致预览线程拿不到帧。解决在 PyQt 里用QThread单独开推理线程摄像头采集和模型推理分离。一个简化版本是这样的class InferenceThread(QThread): result_ready pyqtSignal(str) def run(self): while not self.stop: ok, frame cap.read() if ok: label predict(frame) self.result_ready.emit(label)逻辑说明QThread的子类负责摄像头读取和推理通过pyqtSignal把结果发回主线程更新界面主线程只负责画界面永远不阻塞。参数上要注意cap.read()设置cv2.CAP_PROP_BUFFERSIZE为 1减小缓冲区堆积否则推理速度慢时画面延迟越来越严重。5. 把项目包装成高分课设界面、文档与演示5.1 用 PyQt 搭一个能演示的垃圾分类窗口很多源码包里的 GUI 是用 tkinter 写的虽然能用但答辩观感一般。如果你有多余时间我会建议换成 PyQt 或者干脆加一个 Gradio 网页界面效果非常加分。Gradio 代码特别短很适合做现场演示import gradio as gr def classify(image): result predict(image) return f垃圾分类结果{result} gr.Interface(fnclassify, inputsgr.Image(typepil), outputstext).launch()关键点是inputsgr.Image(typepil)这样 Gradio 会把上传的图片转换成 PIL Image 对象直接和你的predict函数对接。launch()默认启动一个本地网页答辩时可以提前打开浏览器现场拖图片进去就能看结果。Gradio 的优点是零界面代码缺点是打包成 exe 会麻烦一点。如果你想交一个独立可执行文件还是老老实实用 PyQt。5.2 说明文档里必须写清楚的三张表高分项目和普通项目的差别通常在文档。除了常规的系统架构图和功能截图我建议你额外做三张表第一张是“模型对比表”列出不同模型在相同验证集上的准确率、参数量、推理耗时。可以用现成的权重快速跑一遍比如 ResNet18、ResNet50、MobileNetV2。这张表能证明你做过选型分析不是随手抄一个网络。第二张是“类别识别效果表”每一类垃圾统计精确率、召回率和 F1-score。这张表能暴露你对类不均衡问题的理解比如“金属类识别好但塑料瓶和玻璃瓶经常混淆”然后你在文档里写一句“后续用难例挖掘解决”这就是加分项。第三张是“参数配置表”记录学习率、batch size、优化器、数据增强操作。不要写成“参数设置如下”而是写上“为什么这样设置”。老师问到你的时候你能说出依据比任何华丽的界面都管用。5.3 现场演示的细节准备演示最容易翻车的不是模型而是环境。我参加过不少答辩现场最常见的情况是投影仪分辨率到不了界面预设的大小窗口显示不全或者是演示机器上没有安装摄像头驱动或者是现场网络不稳定Gradio 打开后黑屏。解决办法是准备两套演示路径一套是本地图片识别预先在项目根目录放 10 张不同类型垃圾的测试图双击就能出结果另一套是摄像头实时识别但要在自己电脑上提前测通。如果你的模型对摄像头拍的照片分类效果明显不如单反拍的测试图原因在于训练集里缺少手机拍摄的模糊、暗光、强曝光图片答辩前补拍几张放进训练集并重训几轮也是值得做的。另外提前把predict.py改成命令行接收入参的形式演示时可以直接在终端输入python predict.py --image bottle1.jpg比鼠标点按钮更快、更不容易卡顿。老师看到你连给的图都能跑出正确类别印象分会好很多。6. 进阶技巧把固定模型变成可扩展的分类服务6.1 用 JSON 配置文件管理类别映射训练好模型后类别序号和中文名的映射关系经常是硬编码在代码里的比如0:可回收物, 1:有害垃圾。这种写法最怕重新训练一旦数据集的类别顺序变化你得去核对着改。我通常会抽出label_map.json{ 0: 可回收物, 1: 有害垃圾, 2: 厨余垃圾, 3: 其他垃圾 }然后在代码里用json.load读进来任何地方都不再直接写字面量。这样以后想增加“金属瓶、纸箱”新类别只需要扩展数据集并在 JSON 里补一项训练和预测代码一行不用改。6.2 加一个简单的置信度阈值与二次判别模型输出的 softmax 概率并不总是可靠实际里你会发现“纸箱”和“塑料瓶”很像的时候模型会给很低置信度但 argmax 依然选出一个答案。为了避免现场演示时丢人我给预测函数加一个置信度阈值softmax torch.nn.functional.softmax(output, dim1) score, index torch.max(softmax, dim1) if score.item() 0.6: print(置信度不足请更换角度或重新拍摄) else: print(label_map[str(index.item())])参数说明0.6 是个经验值。如果类别之间很模糊可以调到 0.7如果模型准确率不高调高了会导致大量图片识别不了反而尴尬。要处理效果不佳时一个常见做法是在低置信度时对图片做中心放大和水平翻转两次推理取平均概率。这个“测试时数据增强”能稳定提高指标代码也很短。6.3 把模型导出成 ONNX 并用 CPU 推理提速如果最终交付不希望装 PyTorch 全套依赖或者需要在纯 CPU 机器上以更低延迟运行可以把模型导出成 ONNX再用 ONNX Runtime 推理。导出的命令很简单import torch.onnx model.load_state_dict(torch.load(best.pth, map_locationcpu)) model.eval() dummy_input torch.randn(1, 3, 224, 224) torch.onnx.export(model, dummy_input, garbage.onnx, input_names[input], output_names[output], dynamic_axes{input: {0: batch}, output: {0: batch}})注意dynamic_axes里的{0: batch}表示 batch 维度是动态的这样处理单张或多张图片都行。ONNX 模型比 PyTorch 原模型占内存少推理速度在 CPU 上能提升约两成。真正跑起来时用 onnxruntime 的代码比 PyTorch 更简洁import onnxruntime as ort sess ort.InferenceSession(garbage.onnx, providers[CPUExecutionProvider]) output sess.run(None, {input: input_tensor.numpy()})这里providers参数直接指定 CPU避免 Windows 上找不齐 CUDA 的 DLL 导致报错。如果后续想用 GPU把providers改成[CUDAExecutionProvider]就行前提是安装的 onnxruntime-gpu 版本与 CUDA 匹配。做垃圾分类项目做多了我养成的习惯是每换一次数据就重新推一遍同样代码确认不是“换张图就炸”。真正让项目高分的不是那个 zip 名字而是你亲手调参、踩坑、排错的过程。导出 ONNX 这个技巧可能不常用但多花半小时做一次面试或答辩时你能多讲一个别人讲不了的细节。希望这个方向的落地步骤能帮到你动手跑通之后你会发现图像分类的通用套路也就这么多剩下的路都是数据。本文还有配套的精品资源点击获取