基于CNN的垃圾识别分类系统源码解析:从数据集到模型部署

发布时间:2026/9/28 6:17:22

基于CNN的垃圾识别分类系统源码解析:从数据集到模型部署 简介这份资源是面向高校学生与深度学习入门者的垃圾识别分类课程设计完整项目基于卷积神经网络实现图像分类可直接用于期末大作业或课程设计答辩。压缩包共约2000个文件以1196张jpg与789张jpeg图像构成训练与测试数据集另有13个Python源码文件负责模型搭建、训练与推理配合json配置与md说明文档整体约564.69MB目录结构清晰便于按模块查阅与复现。项目已获导师指导并通过据描述取得97分高分下载后无需修改即可运行省去自行收集数据与调试环境的时间。内容预览可见电池、塑料瓶等多类别样本覆盖数据标注、模型训练到分类预测的完整流程适合希望快速掌握CNN图像分类实践、完成课程任务或作为入门练手项目的读者参考。目前已有263人学习关注。1. 从一张img_电池_452.jpeg说起这套 CNN 垃圾识别源码到底能跑出什么你拿到手的这个压缩包解压后第一眼看到的不是train.py而是一堆命名规整的图片img_电池_452.jpeg、img_塑料瓶_244.jpeg、img_塑料瓶_67.jpeg、img_电池_541.jpeg……文件名里直接带了类别标签和序号。这不是随手拍的数据集而是已经按「电池 / 塑料瓶」等类别做过粗分拣的原始素材文件名本身就是弱监督信号。整套资源是一份基于卷积神经网络的垃圾识别分类系统 Python 源码附带数据集和训练好的模型定位很明确课程设计、期末大作业下载解压后能直接跑通推理也能自己重训。它解决的核心问题不是「从零教你 CNN」而是把数据组织、模型定义、训练循环、推理脚本、模型保存这一整条链路打包好让你不用在环境配置和目录结构上反复翻车。适合两类人一类是赶课程设计 deadline、需要一份结构完整且能演示的项目另一类是刚学完卷积神经网络原理想找一个真实小数据集把Conv2d、MaxPool2d、CrossEntropyLoss这些概念落到代码里的人。下面我按「资源结构 → 数据管线 → 模型与训练 → 推理与验证 → 避坑 → 进阶」的顺序拆每一步都给出可抄的参数和命令。2. 拆包看结构数据集、模型文件与训练脚本怎么摆2.1 先确认目录布局别急着装环境拿到压缩包后我一般先不碰 Python而是用tree或文件管理器把层级看清楚。这类课程设计项目的典型结构是一个dataset目录按类别分子文件夹一个model目录放.pth权重根目录下若干.py脚本。图片文件名里的img_电池_452.jpeg这种格式说明数据在采集阶段就按类别命名但真正喂给网络时靠的是它所在的父文件夹名而不是文件名本身。# 查看解压后的目录层级重点看 dataset 和 model 两个目录 unzip 垃圾识别分类系统.zip -d trash_cnn cd trash_cnn find . -maxdepth 3 -type d | sort # 统计每个类别下的图片数量确认有没有空文件夹或数量严重不均 for d in dataset/*/; do echo -n $d: ; ls $d | wc -l; done逻辑说明find -maxdepth 3只展开三层避免数据集图片太多刷屏第二个循环按类别统计数量是为了提前发现类别不平衡。参数上maxdepth根据你的实际层级调整如果类别文件夹在dataset/train/下就改成 4。这一步不做后面训练时 loss 不下降你都不知道是模型问题还是某个类别只有三张图。2.2 数据集划分与文件名标签的取舍文件名里的中文类别电池、塑料瓶在 Windows 下没问题但跨平台传到 Linux 或某些 Python 库读取时中文路径是高频翻车点。常见做法是保留原始图片但在生成训练列表时用父目录名做标签而不是解析文件名。这样即使文件名编码乱了只要文件夹名是英文或拼音管线就稳。目录/文件作用是否可改dataset/电池/电池类原始图片可增删需保持类别名一致dataset/塑料瓶/塑料瓶类原始图片同上model/best.pth训练好的权重可替换需匹配网络结构train.py训练入口可调超参predict.py单张推理改图片路径即可提示如果解压后类别文件夹是中文名先别重命名跑一遍python -c import os; print(os.listdir(dataset))确认 Python 能正常读出再决定是否改成拼音。3. 数据管线与预处理把img_电池_452.jpeg变成张量3.1 用ImageFolder还是手写Dataset这类项目数据组织成「一个类别一个文件夹」最省事的是torchvision.datasets.ImageFolder它会自动按文件夹名生成class_to_idx。但课程设计里经常需要自定义增强或处理文件名标签所以源码里也可能手写Dataset。两种都能用区别在于ImageFolder要求目录结构严格手写Dataset灵活但容易在__getitem__里写错返回顺序。import os from PIL import Image from torch.utils.data import Dataset, DataLoader from torchvision import transforms class TrashDataset(Dataset): def __init__(self, root, transformNone): self.samples [] self.transform transform # 遍历每个类别文件夹用文件夹名作为标签 self.classes sorted(os.listdir(root)) self.class_to_idx {c: i for i, c in enumerate(self.classes)} for c in self.classes: c_dir os.path.join(root, c) if not os.path.isdir(c_dir): continue for fname in os.listdir(c_dir): if fname.lower().endswith((.jpg, .jpeg, .png)): self.samples.append((os.path.join(c_dir, fname), self.class_to_idx[c])) def __len__(self): return len(self.samples) def __getitem__(self, idx): path, label self.samples[idx] img Image.open(path).convert(RGB) # 统一转 RGB防止灰度图报错 if self.transform: img self.transform(img) return img, label # 训练增强随机裁剪翻转验证只做缩放和归一化 train_tf transforms.Compose([ transforms.Resize((224, 224)), transforms.RandomHorizontalFlip(), transforms.RandomRotation(10), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) val_tf transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ])逻辑说明__getitem__里convert(RGB)是关键数据集里如果有单通道图或带 alpha 通道的 PNG不转会在ToTensor后维度对不上。Normalize用的均值方差是 ImageNet 统计值因为后面大概率用预训练权重保持一致能少调一个参数。Resize((224, 224))对应 ResNet 系列输入如果你换自定义小网络可以降到 64 或 128但别低于 32否则池化几次特征图就没了。3.2DataLoader的 batch 与 shuffle 怎么定train_ds TrashDataset(dataset/train, transformtrain_tf) val_ds TrashDataset(dataset/val, transformval_tf) train_loader DataLoader(train_ds, batch_size32, shuffleTrue, num_workers2) val_loader DataLoader(val_ds, batch_size32, shuffleFalse, num_workers2)参数说明batch_size32是课程设计里比较稳的值显存不够就降到 16 或 8shuffleTrue只在训练集开验证集必须 False否则评估指标会随顺序波动num_workers在 Windows 下有时会卡死设 0 最稳Linux 下可以设 2 到 4。如果数据集图片总数只有几百张batch_size别超过 64否则一个 epoch 只有几步loss 曲线会很难看。4. 卷积网络搭起来从Conv2d到CrossEntropyLoss4.1 自定义 CNN 还是迁移学习课程设计常见两种写法一种是从头搭一个 3 到 5 层的 CNN另一种是加载resnet18预训练权重改最后一层。前者代码短、依赖少适合展示对卷积神经网络结构的理解后者精度高、收敛快适合数据量少的情况。如果数据集只有电池和塑料瓶两类且每类几百张自定义 CNN 完全够用如果类别多、图片杂迁移学习更省事。import torch.nn as nn import torchvision.models as models # 方案一自定义轻量 CNN class SimpleCNN(nn.Module): def __init__(self, num_classes2): super().__init__() self.features nn.Sequential( nn.Conv2d(3, 32, 3, padding1), nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(32, 64, 3, padding1), nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(64, 128, 3, padding1), nn.ReLU(), nn.MaxPool2d(2), ) self.classifier nn.Sequential( nn.AdaptiveAvgPool2d(1), # 自适应池化避免全连接维度算错 nn.Flatten(), nn.Linear(128, num_classes) ) def forward(self, x): return self.classifier(self.features(x)) # 方案二迁移学习改 resnet18 最后一层 def build_resnet(num_classes2): model models.resnet18(weightsmodels.ResNet18_Weights.DEFAULT) model.fc nn.Linear(model.fc.in_features, num_classes) return model逻辑说明AdaptiveAvgPool2d(1)是新手最容易忽略的一步它把任意尺寸的特征图压成 1x1这样输入图片尺寸变了也不用改全连接层。padding1配合kernel_size3保持特征图尺寸只在池化时减半。迁移学习方案里weightsDEFAULT会自动下载预训练权重如果环境不能联网需要提前把权重文件放到缓存目录否则会卡在下载。4.2 训练循环与学习率设置import torch from torch import optim device torch.device(cuda if torch.cuda.is_available() else cpu) model SimpleCNN(num_classeslen(train_ds.classes)).to(device) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr1e-3) for epoch in range(20): model.train() total_loss 0 for imgs, labels in train_loader: imgs, labels imgs.to(device), labels.to(device) optimizer.zero_grad() out model(imgs) loss criterion(out, labels) loss.backward() optimizer.step() total_loss loss.item() print(fepoch {epoch1}, loss {total_loss/len(train_loader):.4f})参数说明lr1e-3是 Adam 的常用起点如果 loss 震荡就降到 1e-4epoch20对几百张图的小数据集通常够但要看验证集准确率是否还在涨。CrossEntropyLoss内部已经包含 softmax所以模型最后一层不要加Softmax否则等于做了两次梯度会出问题。训练时如果显存不够把batch_size减半或者把输入尺寸从 224 降到 128。5. 推理、验证与模型保存别让best.pth变成黑匣子5.1 单张图片推理脚本from PIL import Image import torch def predict(image_path, model, class_names, transform, device): model.eval() img Image.open(image_path).convert(RGB) tensor transform(img).unsqueeze(0).to(device) # 增加 batch 维度 with torch.no_grad(): out model(tensor) prob torch.softmax(out, dim1) pred prob.argmax(dim1).item() return class_names[pred], prob[0][pred].item() # 用法 model.load_state_dict(torch.load(model/best.pth, map_locationdevice)) name, score predict(img_电池_452.jpeg, model, train_ds.classes, val_tf, device) print(name, score)逻辑说明unsqueeze(0)把单张图的[C,H,W]变成[1,C,H,W]因为模型 forward 默认按 batch 处理。torch.no_grad()关闭梯度计算省显存也提速。map_locationdevice保证在 CPU 上也能加载 GPU 训练的权重这是跨设备推理的后悔药。val_tf不能带随机增强否则同一张图每次预测结果可能不同。5.2 验证集评估与混淆矩阵from sklearn.metrics import confusion_matrix, classification_report model.eval() all_preds, all_labels [], [] with torch.no_grad(): for imgs, labels in val_loader: imgs imgs.to(device) out model(imgs) preds out.argmax(dim1).cpu().numpy() all_preds.extend(preds) all_labels.extend(labels.numpy()) print(classification_report(all_labels, all_preds, target_namestrain_ds.classes)) print(confusion_matrix(all_labels, all_preds))参数说明classification_report会给出每个类别的 precision、recall、f1比只看总体准确率有用。如果某一类 recall 特别低说明该类样本被大量误判常见原因是样本太少或增强过度。混淆矩阵能直接看出「电池被认成塑料瓶」还是「塑料瓶被认成电池」对应去补数据或调权重。6. 避坑与排查这几处翻车我替你踩过了6.1 中文路径导致Image.open报错现象在 Windows 上跑得好好的换到 Linux 或打包成 exe 后Image.open抛FileNotFoundError或乱码。原因文件系统编码不一致中文文件夹名在某些 Python 版本下解析失败。解决把类别文件夹改成拼音或英文或者在代码里用os.fsencode/os.fsdecode包一层最稳的是统一改成英文目录名。6.2 训练 loss 不降准确率卡在 50%现象二分类任务loss 一直在 0.69 附近准确率等于瞎猜。原因标签和输出维度对不上或者CrossEntropyLoss前又加了Softmax。解决检查num_classes是否等于类别数检查模型最后一层输出维度去掉多余的Softmax。另外确认DataLoader的shuffle在训练集为 True。6.3 验证集准确率远低于训练集现象训练集 99%验证集 60%。原因数据量太小、增强过猛或者训练集和验证集有重复图片。解决先检查两个集合有没有同名文件再降低增强强度比如去掉RandomRotation必要时用迁移学习替代从头训练。6.4num_workers在 Windows 下卡死现象程序启动后不动CPU 占用为 0。原因Windows 下多进程 DataLoader 和if __name__ __main__保护不兼容。解决把num_workers设为 0或者把训练代码包进if __name__ __main__:里。6.5 模型保存后加载报Missing key(s)现象load_state_dict报缺少键或多余键。原因保存时用了torch.save(model, path)整个模型加载时又用load_state_dict或者网络结构改过。解决统一用torch.save(model.state_dict(), path)保存权重加载前先实例化同结构模型再load_state_dict。7. 进阶技巧把 97 分项目改成能演示的完整系统课程设计交完不是终点这套源码稍微改改就能当作品集里的演示项目。我一般会做三件事第一把predict.py包一层argparse支持命令行传图片路径和模型路径这样演示时不用改代码第二加一个requirements.txt把torch、torchvision、Pillow、scikit-learn的版本钉死避免换机器后环境崩掉第三用torch.jit.trace把模型导出成 TorchScript推理时不再依赖源码里的类定义。import argparse import torch if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(--img, typestr, requiredTrue, help待识别图片路径) parser.add_argument(--model, typestr, defaultmodel/best.pth) args parser.parse_args() # 加载模型并推理输出类别和置信度 # 具体加载逻辑复用第 5 章 predict 函数参数说明requiredTrue强制传图片路径避免空跑default给模型路径一个默认值演示时少敲几个字。导出 TorchScript 的常见做法是example torch.rand(1, 3, 224, 224).to(device) traced torch.jit.trace(model, example) traced.save(model/traced_model.pt)这样部署时只需要torch.jit.load不用再带.py文件。验证方法也简单拿一张训练时没见过的img_塑料瓶_67.jpeg分别用原始模型和 TorchScript 模型跑一遍看输出类别和置信度是否一致差太多说明 trace 时漏了动态分支。从那以后我每次拿到这类课程设计源码都强制先跑一遍find统计类别数量再拿一张图走完推理确认best.pth和网络结构对得上才敢动训练脚本。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/28 6:17:22

达梦数据库容器化部署SSL加密配置与排障实战指南

最近在把达梦数据库从裸机迁到容器环境,顺手把客户端到服务端的连接改成SSL加密。这套流程涉及docker和k8s两种部署形态,踩坑最多的地方反而不是数据库本身,而是证书生成、文件挂载、配置持久化这些容器环境特有的环节。我把完整的配置流程、…

2026/9/28 6:17:22

Kafka Java系统设计核心:生产消费封装、位点管理与避坑调优实战

简介:这套基于Java语言的Kafka消息队列系统设计源码,面向需要处理高吞吐量消息、构建实时数据管道或学习分布式中间件原理的Java开发者。项目共42个文件,压缩包约77.3MB,主要包含27个Java源文件、6个XML配置文件、1个YAML配置、属…

2026/9/28 6:12:21

Vector AUTOSAR SIP包本质解析:汽车电子BSW集成契约与合规开发指南

1. 这不是买个软件装上就能跑的“开箱即用”,而是一场嵌入式汽车电子开发者的系统性通关Vector AUTOSAR SIP包——这个在汽车电子圈里被反复提及、却常被误解为“Vector家的AUTOSAR套件”的名词,本质上根本不是一款现成可用的软件产品,而是一…

2026/9/28 7:12:24

竞赛管理系统源码详解:SpringBoot+Vue+MyBatis架构与高校业务闭环

做了不少高校信息化项目,竞赛管理系统属于那种"看着简单、细节多到爆炸"的类型。报名信息散落在导员的Excel表里,作品提交靠U盘拷贝,评审打分标准不统一,统计报表每学期都得重新拉一次数据。今年完整整理出一套基于Spri…

2026/9/28 7:12:24

OpenCV C++手掌图像测量:手指长宽毫米级提取与标定

简介:这份资源面向计算机视觉课程设计、OpenCV入门实践者及需要完成手掌参数测量项目的学生,提供一套基于C与OpenCV的完整实现方案。项目通过摄像头采集完整手掌图像,综合运用滤波、边缘检测、角点检测与霍夫变换等图像处理技术,精…

2026/9/28 7:12:24

命令行工具生态实战:从单条命令到自动化工作流的进阶指南

我写过十几年脚本,也见过不少人把命令行工具玩出花的场景。但老实说,真正让我觉得“Amazing”的项目,不是那些靠复杂配置撑起来的重量级框架,反而是像 CLI-Anything 这一路的东西——它把“用命令行搞定一切”这个理念做到了极致&…

2026/9/28 7:12:24

Redisson分布式锁从原理到实战:解决并发互斥与自动续期

如果你在面试或实际开发中被问到“分布式锁”,Redisson 基本是绕不开的名字。这几年我面试别人的时候,几乎每次都会问“分布式锁你怎么实现”,答案从SETNX手写、到 ZooKeeper 临时节点、再到 Redisson 都有。但聊到最后大家基本都会承认&…

2026/9/28 3:03:23

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/9/28 6:05:15

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/28 6:07:41

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/28 0:02:03

广州外贸网站建设推广:从零搭建全流程拆解与真实报价避坑

广州外贸网站建设推广:从零搭建全流程拆解与真实报价避坑 改个需求建站公司拖一周,后台改个文案还得再交一笔“技术维护费”。这种憋屈事儿,做外贸的朋友太熟悉了。很多老板在找广州外贸网站建设推广服务商时,光盯着首页好不好看,却忽略了从零搭建一个能…

2026/9/28 0:02:04

搞懂百度竞价推广价格,网站性能优化别掉链子

搞懂百度竞价推广价格,网站性能优化别掉链子 网站突然打不开,浏览器弹出红色警告“此网站存在安全风险”,后台一看全是乱码代码和奇怪的跳转链接。这种网站被黑挂马的绝望感,很多刚转行做网站的朋友都经历过,尤其是那些为了省几百块钱服务器费用的新手。…

2026/9/25 20:55:38

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/26 19:58:38

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/28 1:59:25

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑