news 2026/9/10 14:05:26

基于卷积神经网络的垃圾分类系统从零搭建与调参实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于卷积神经网络的垃圾分类系统从零搭建与调参实战

简介:一份基于卷积神经网络的垃圾分类系统Python毕业设计资料,面向计算机相关专业正在准备毕业设计的学生,以及需要项目实战练习的初学者。项目经导师指导审定,评审得分98分,源码已本地编译调试通过,可稳定运行,适合作为课程设计、期末大作业或毕业设计的参考范本。资源以压缩包形式提供,整体约5.1MB,包含完整项目源码与配套论文PDF;源码模块覆盖垃圾分类模型的构建、训练与识别流程,论文则可用于理解系统设计思路与实现细节。目前已有156人学习下载。对于想要快速搭建深度学习图像识别项目、掌握卷积神经网络实际应用的同学,这份资源既能提供可运行的代码基础,也能借助论文厘清原理与排错思路,帮助节省选题与开发时间。

1. 基于卷积神经网络的垃圾分类系统,毕业设计到底要做成什么样

毕业设计题目拿到手,很多人第一反应是“分类模型网上有现成的,源码抄一抄就行”,实际答辩时却连训练曲线都解释不清楚。这个标题的核心不是“识别准确率有多高”,而是用 Python 把卷积神经网络在垃圾分类场景下完整落地:数据怎么整理、模型怎么搭、训练怎么收敛、最终怎么演示,以及论文里每一项实验数据从哪里来。我需要先说清楚,这类系统本质是图像分类任务,CNN 负责从图片中自动提取颜色、纹理、边缘到局部形状特征,比手工特征工程更省事。适合计算机、人工智能、物联网方向的学生,也适合想快速搭一套可演示系统的开发者。先想清楚交付物边界,后面才不会返工。

2. 垃圾分类系统的需求拆解与CNN选型依据

一个可答辩的垃圾分类系统,通常包含四部分:图片输入、特征提取、分类输出、结果展示和论文佐证。在写代码前,先把需求拆成硬性和软性。硬性需求是模型能在本地 GPU 或 CPU 上完成训练和推理;软性需求是界面要简单、训练过程要能复现、论文里要有数据支撑。不建议一上来就追求多类别,常见做法是先固定 4 类:其他垃圾、可回收物、厨余垃圾、有害垃圾,再往下细分塑料、玻璃、纸张等。类别数量影响数据集规模和数据均衡程度,这直接决定后边要不要做数据增强。

2.1 先定类别体系,再定数据集规模

垃圾类别没有一个全球统一标准,国内做毕业设计最常见的是按《生活垃圾分类标志》分四类,也有项目为了体现工作量拆成几十类。我的经验是:如果从零开始做,4 类或 6 类最稳妥。类别太少显得没工作量,类别太多容易出现“同一张图在不同数据源里标签不一致”的问题。

数据规模方面,每类图片最好不少于 300 张。300 张只是下限,如果能到 1000 张,训练效果会有明显改善。数据可以来自开源数据集,也可以自己拍照、爬取公开图片再人工清洗。注意爬取图片时要手动去掉截图和重复图,噪声会直接反映在验证集准确率上。开始训练前,先用一段小脚本确认数据分布:

from pathlib import Path data_root = Path("dataset/train") for cls_dir in sorted(data_root.iterdir()): img_count = sum(1 for p in cls_dir.rglob("*") if p.suffix.lower() in {".jpg", ".png", ".jpeg"}) print(f"{cls_dir.name}: {img_count} 张")

这里用rglob("*")而不是glob("*"),是因为有的数据集会把同一类图片放在多级子目录里;后缀判断里加.jpeg是为了兼容常见图片格式。如果发现某个类明显比其他类少,就需要补数据或做数据增强,不要等到训练完再看分类报告。

2.2 为什么这类任务默认用卷积神经网络而不是全连接网络

垃圾分类看的是图像内容,不是像素点的绝对位置。全连接网络会把每个像素当作独立特征,两张内容相同但位置有微小偏移的图片,在全连接网络里可能被当成完全不同的东西。卷积神经网络通过卷积核在图像上滑动,每次只看一小块局部区域,再通过堆叠卷积层把局部特征组合成高阶特征。

这里的几个名词要摊开讲:卷积核(kernel)是一个小矩阵,比如 3×3;步长(stride)是卷积核每次滑动的距离;填充(padding)是在图像边缘补零,目的是控制输出尺寸;池化(pooling)做下采样,最常见的是最大池化,取窗口内的最大值,这样能让模型对微小位移鲁棒。一个典型结构是:输入图片 → 卷积 + ReLU → 池化 → 再卷几轮 → 展平 → 全连接输出。后文第四章给出的代码就是按这个顺序写的,卷积层负责提取特征,池化层负责缩小特征图尺寸,全连接层负责把特征映射到类别概率。

2.3 自己搭 CNN 和用 ResNet 迁移学习怎么选

如果论文想重点讲网络结构设计,就自己搭一个 3 到 4 层卷积的小网络,训练快,参数好解释;如果数据量不够,用 PyTorch 里现成的 ResNet18 做迁移学习,去掉最后的全连接层,换成自己的分类头,准确率会明显更高。我的建议是两手都做:先写一个自定义 CNN 作为 baseline,再迁移学习一个 ResNet18 做对比,论文实验部分就有两组数据了。下面是一份选型对比表,帮你在开题阶段就确定主线:

方案数据集要求训练速度准确率起点论文价值适用场景
自建 3 层 CNN每类 300+ 张快,CPU 可跑75% 左右结构可解释,参数好写强调网络设计
ResNet18 迁移学习每类 100 张也能跑需要 GPU 或较慢 CPU90% 左右方法成熟,重点在调参强调实际工程效果

注意:准确率起点是典型参考范围,不是固定值,最终论文里写的是你自己跑出来的结果。迁移学习也不是无脑换模型,输入图片要缩放成预训练模型要求的尺寸,数据标准化要跟着预训练统计量走,这些在下一章会体现。

3. 数据集预处理与PyTorch数据管线搭建

模型结构先放一边,数据管线是第一个坑。很多同学在一个文件夹里放所有图片,然后用一个 CSV 文件记录标签,跑起来没问题,但论文里不好描述,答辩也不好解释数据划分。我建议直接用“train / val 两个目录,每个类别一个子目录”的结构,和torchvision.datasets.ImageFolder、自定义 Dataset 都能无缝衔接。

3.1 数据目录怎么组织,训练集和验证集不能混

典型目录结构如下:

dataset/ ├── train/ │ ├── other/ │ ├── recyclable/ │ ├── kitchen_waste/ │ └── hazardous/ └── val/ ├── other/ ├── recyclable/ ├── kitchen_waste/ └── hazardous/

训练集和验证集按目录分开,不要在代码里做随机切分时把同源图片同时分到两边。尤其自己拍照时,同一物体的多张相似照片不应同时出现在训练集和验证集,否则验证集准确率虚高,答辩时容易被问穿。常见做法是按 8:2 分层抽样,每个类别独立切,保证每个类别在验证集里都有样本。

3.2 用 torchvision.transforms 做预处理和数据增强

PyTorch 的数据预处理核心是torchvision.transforms。训练集用随机的数据增强来增加多样性,验证集只做缩放和标准化,不做随机翻转和旋转,否则评估结果不稳定。下面是一组常见配置:

from torchvision import transforms train_transforms = transforms.Compose([ transforms.Resize((224, 224)), transforms.RandomHorizontalFlip(p=0.5), transforms.RandomRotation(degrees=15), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) val_transforms = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ])

这里Resize((224, 224))把图片统一成 224×224,这是 ImageNet 预训练模型的常用输入尺寸;RandomHorizontalFlipRandomRotation让模型看到更多样化的垃圾摆放角度,对瓶罐、纸盒这类方向性弱的类别比较有效;Normalize使用 ImageNet 的均值和标准差,目的是让输入分布接近预训练权重的假设。如果完全从零训练 CNN,Normalize仍然建议保留,可以加快收敛。

常用变换的参数需要记住,论文里往往要列一张表:

变换参数作用建议
Resize尺寸元组统一图片大小224×224 或 256×256
RandomHorizontalFlipp=0.5水平翻转增强对文字类图片要慎用
RandomRotationdegrees=15小角度旋转旋转过大破坏物体结构
ColorJitterbrightness/contrast亮度对比度变化适合光线不均的实拍图
ToTensor转为 Tensor 并缩放到 [0,1]必须
Normalizemean/std标准化与预训练模型匹配

3.3 自定义 Dataset 读取图片并划分数据

ImageFolder可以直接用目录结构生成数据集,但自定义 Dataset 更方便在论文里展示你处理了哪些字段,也方便以后加标签平滑或辅助信息。下面是一个最小实现:

from torch.utils.data import Dataset from PIL import Image class GarbageDataset(Dataset): def __init__(self, root_dir, transform=None): self.samples = [] self.transform = transform for cls_id, cls_name in enumerate(sorted(root_dir.iterdir())): for img_path in cls_name.rglob("*"): if img_path.suffix.lower() in {".jpg", ".png", ".jpeg"}: self.samples.append((img_path, cls_id)) def __len__(self): return len(self.samples) def __getitem__(self, idx): img_path, label = self.samples[idx] img = Image.open(img_path).convert("RGB") if self.transform: img = self.transform(img) return img, label

enumerate(sorted(root_dir.iterdir()))保证了类别顺序固定,同一个类别文件夹在每次运行里拿到相同的索引,这对后续计算混淆矩阵很重要。Image.open(...).convert("RGB")强制转成 RGB,防止某些灰度图或带透明通道的 PNG 导致通道数不匹配。实例化后,用DataLoader分批取数据:

from torch.utils.data import DataLoader train_dataset = GarbageDataset("dataset/train", transform=train_transforms) val_dataset = GarbageDataset("dataset/val", transform=val_transforms) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=2) val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False, num_workers=2)

shuffle=True只对训练集开启,验证集保持固定顺序评测;num_workers根据电脑内存调整,Windows 上设 0 或 2,Linux 可以更高。数据管线到这里就能跑通了,下一步才是把网络结构写出来。

4. 构建卷积神经网络:卷积、池化、步长、核、填充的落地写法

数据准备好了,开始写模型。这里不会贴很长的成熟网络,而是从零搭一个能跑通、能解释的 CNN,把卷积、池化、步长、核、填充这些概念落进 PyTorch 代码里。论文的“网络结构设计”一章可以直接引用这段代码,配一张自己画的流程框图。

4.1 卷积层参数:in_channels、out_channels、kernel_size、stride、padding

nn.Conv2d的构造参数里,in_channels是输入特征图通道数,RGB 图第一次卷积是 3,后面每经过一层卷积,out_channels就是这一层卷积核的数量,同时也是输出特征图的通道数。kernel_size是卷积核尺寸,stride是步长,padding是补零圈数。输出尺寸计算公式是:

输出边长 = (输入边长 + 2 * padding - kernel_size) / stride + 1

这个公式要刻进脑子里。例如输入 224×224,kernel_size=3, stride=1, padding=1,输出仍是 224×224;下一层MaxPool2d(2)把尺寸减半成 112×112。反复卷、池化之后,特征图尺寸会变成 28×28,最后展平成一维向量接全连接层。

各参数的常见取值和作用,可以直接放在论文“参数设置”小节里:

参数常见值作用注意点
in_channels3/16/32/64输入特征图通道数上一层输出通道必须一致
out_channels16/32/64/128卷积核数量数量越多特征越丰富,计算量越大
kernel_size3/5卷积核尺寸3×3 最常用,两个 3×3 等效一个 5×5 的感受野
stride1/2滑动步长stride=2 可以直接下采样
padding0/1边缘补零保持尺寸时用 padding=1

4.2 一个能跑通的 CNN 网络结构示例

下面这个GarbageCNN是三段“卷积+池化”结构,输入 224×224 彩图,输出 4 类概率。代码量不大,CPU 也能在合理时间内跑完 15 轮:

import torch.nn as nn class GarbageCNN(nn.Module): def __init__(self, num_classes=4): super().__init__() self.features = nn.Sequential( nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(2), nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(2), nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(2), ) self.classifier = nn.Sequential( nn.Flatten(), nn.Linear(64 * 28 * 28, 128), nn.ReLU(inplace=True), nn.Dropout(0.5), nn.Linear(128, num_classes) ) def forward(self, x): return self.classifier(self.features(x))

三个MaxPool2d(2)会把 224×224 逐步压到 112×112、56×56、28×28,所以全连接层输入维度是64 * 28 * 28Dropout(0.5)放在全连接前,训练时随机丢弃一半神经元,有助于缓解过拟合。如果你改成 ResNet18,这段代码不需要直接保留,但理解这个结构能帮你解释迁移学习里“替换分类头”是什么意思。

4.3 损失函数、优化器和训练闭环

图像分类默认用交叉熵损失,优化器用 Adam 起步,学习率从 1e-3 开始。下面的训练循环是完整的,可以直接放到train.py里:

import torch.optim as optim model = GarbageCNN(num_classes=4) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=1e-3) for epoch in range(1, 16): model.train() total_loss = 0.0 for images, labels in train_loader: optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() total_loss += loss.item() * images.size(0) avg_loss = total_loss / len(train_dataset) print(f"epoch {epoch} | loss {avg_loss:.4f}")

optimizer.zero_grad()在每次迭代前清零梯度,否则 PyTorch 会默认累积梯度;loss.backward()计算梯度,optimizer.step()更新参数。这段代码没有做验证和模型保存,更完整的版本会在下一章补齐,因为要配合调参和实验记录一起写,不然你无法判断第几轮最好。

5. 训练调参与实验记录,论文里的图表从哪来

训练不只是“跑起来”,毕业设计论文里需要训练曲线、准确率对比、混淆矩阵,所以每一轮实验都要留下记录。常见做法是每轮同时做验证集评估,保存验证集准确率最高的权重,并把 loss 和 acc 写进日志文件。这样论文里的图表就不是事后补画的,而是训练过程中自动生成的。

5.1 影响收敛的三个关键参数:学习率、Batch Size、Epoch

学习率太大,loss 会震荡;太小又收敛太慢。Adam一般从1e-3开始,如果验证准确率在 10 轮后还在 60% 以下,降到1e-4重试。Batch Size 决定每次更新参数看到的样本数,32 是平衡显存和稳定性的常用起点;显存不够就降到 16,但不要降到 1,否则梯度噪声很大。Epoch 不是一个需要拍脑袋定的参数,应该配合早停来设上限。

参数推荐起点范围说明过小/过大的表现
learning rate1e-3 (Adam)1e-4 到 1e-2过小收敛慢,过大 loss 震荡
batch size3216 到 64过小不稳定,过大显存不够
epoch20 上限配合早停epoch 太多会过拟合
optimizerAdamSGD+momentum 也行Adam 鲁棒,SGD 调好了更稳

5.2 训练循环、验证逻辑和模型保存

下面是带验证和保存最优权重的完整代码。注意验证阶段必须用model.eval()torch.no_grad()

from tqdm import tqdm best_acc = 0.0 patience = 0 max_patience = 5 for epoch in range(1, 21): model.train() train_loss = 0.0 for images, labels in tqdm(train_loader, desc=f"epoch {epoch}"): optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() train_loss += loss.item() * images.size(0) model.eval() correct = 0 total = 0 with torch.no_grad(): for images, labels in val_loader: outputs = model(images) _, predicted = torch.max(outputs, 1) total += labels.size(0) correct += (predicted == labels).sum().item() val_acc = 100.0 * correct / total print(f"epoch {epoch} | loss {train_loss / len(train_dataset):.4f} | val_acc {val_acc:.2f}%") if val_acc > best_acc: best_acc = val_acc torch.save(model.state_dict(), "best_model.pth") patience = 0 else: patience += 1 if patience >= max_patience: print("early stop") break

torch.max(outputs, 1)返回每行最大值和对应索引,索引就是预测类别编号。model.eval()会关闭 Dropout,torch.no_grad()关闭梯度计算,这两行缺一不可。保存模型时只保存state_dict()而不是整个模型,答辩时更清晰,也方便迁移到部署脚本。

5.3 用训练日志自动生成论文图表

把每轮的train_lossval_acc存到两个列表里,训练结束直接用 Matplotlib 画曲线,并保存成 PNG 放进论文。代码很简单:

import matplotlib.pyplot as plt plt.figure(figsize=(8, 4)) plt.plot(range(1, len(train_losses) + 1), train_losses, marker="o", label="train loss") plt.xlabel("epoch") plt.ylabel("loss") plt.title("Training loss curve") plt.grid(True) plt.legend() plt.savefig("figures/train_loss_curve.png", dpi=200)

再画一张验证准确率曲线,用相同方式保存到figures/目录。论文里“实验与分析”一节放这两张图,再配一个分类报告或混淆矩阵,就足够支撑结论了。混淆矩阵可以用sklearn.metrics.confusion_matrix对验证集统一预测后生成,注意类别顺序要和训练时一致,否则横纵坐标对不上。如果你使用迁移学习,把同样的数据丢给 ResNet18 再跑一遍,得到第二条曲线,两张图对比,论文技术含量直接上来了。

6. 用 Gradio 快速搭出可演示页面,再把源码和论文PDF整理成附件

6.1 用 Gradio 把模型包装成上传图片即出分类结果

演示环节不要写复杂 Web 后端,用 Gradio 几十行就能搞定。Gradio 会自动生成上传控件和结果展示,适合开题、中期、答辩现场直接运行。在app.py里加载训练好的模型和val_transforms,定义预测函数后启动:

import gradio as gr import torch model = GarbageCNN(num_classes=4) model.load_state_dict(torch.load("best_model.pth", map_location="cpu")) model.eval() labels = ["other", "recyclable", "kitchen_waste", "hazardous"] def predict(img): tensor = val_transforms(img).unsqueeze(0) with torch.no_grad(): logits = model(tensor) pred_idx = torch.argmax(logits, dim=1).item() return {labels[i]: float(logits[0, i]) for i in range(len(labels))} gr.Interface( fn=predict, inputs=gr.Image(type="pil"), outputs=gr.Label(num_top_classes=4), title="垃圾分类识别" ).launch(share=False)

val_transforms(img).unsqueeze(0)把单张图片补成 batch 维度,share=False是在本地演示,如果需要手机在同局域网调试可以加server_port=7860固定端口。输出用gr.Label显示每个类别的置信度,比只显示字符串更能体现“模型不是乱猜”。

6.2 源码结构和论文PDF整理的常见做法

源码建议按功能拆文件:data_loader.py负责 Dataset 和数据增强,model.pyGarbageCNNtrain.py放训练循环,app.py放 Gradio 界面,requirements.txt写死主要依赖版本。论文 PDF 在封面和目录之外,一定要包含:数据预处理过程、网络结构图、训练超参数表、loss/acc 曲线、验证集混淆矩阵和演示截图。提交时把源码、训练好的best_model.pth、论文 PDF 放在一个文件夹里,README 里写明“先装依赖,再跑python train.py,然后python app.py”三步操作,答辩老师照着就能完整复现。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 14:04:15

FDC2214与STM32高精度电容检测硬件协同设计指南

简介:本资源是一套面向嵌入式开发初学者与进阶工程师的STM32FDC2214高精度电容测量参考设计,聚焦电容式传感器在触摸检测、湿度/压力传感等场景中的工程落地。内容涵盖中文技术文档、完整Keil工程源码(含HAL库驱动与IC通信实现)、…

作者头像 李华
网站建设 2026/9/10 14:00:18

CANN/GE图切分保存接口

ShardGraphsToFile 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、TensorF…

作者头像 李华
网站建设 2026/9/10 13:57:04

Ceph分布式存储系统演进与性能优化关键技术

1. Ceph存储系统的演进与核心变革Ceph作为开源的分布式存储系统,在过去十年间经历了从实验室项目到企业级基础设施的关键蜕变。我最早在2013年接触Ceph 0.67版本时,其部署还需要手动编辑大量配置文件,而现在的Luminous/Nautilus版本已经实现了…

作者头像 李华
网站建设 2026/9/10 13:54:40

全端云会员系统架构与精准运营实战指南

1. 全端云会员系统的商业价值解析 在零售行业竞争白热化的今天,商家面临的最大痛点莫过于如何有效识别顾客、追踪消费行为并建立长期互动关系。传统会员体系往往受限于数据孤岛和渠道割裂,而全端云会员系统正是破解这一困局的利器。这套系统通过云端统一…

作者头像 李华
网站建设 2026/9/10 13:54:12

多元线性回归预测信用卡客户价值:从建模到项目交付的完整方案

简介:Python多元线性回归信用卡客户价值预测项目是一份面向数据分析初学者及课程设计人群的完整源码包,围绕银行客户价值数据展示从数据读取、模型搭建、方程构造到评估预测的完整流程,适合用于毕业设计、实训作业或答辩参考。压缩包共34个文…

作者头像 李华