首页 / 资讯中心 / 文章详情

基于YOLOv5与微信小程序的生活垃圾智能分类系统全链路实战

基于YOLOv5与微信小程序的生活垃圾智能分类系统全链路实战 ★ FEATURED ARTICLE
垃圾分类这件事我从几年前就开始折腾最初用传统图像处理方法做调阈值调到怀疑人生后来切到深度学习才算真正跑通。这次要聊的是一套完整的生活垃圾智能分类系统技术栈是微信小程序加YOLOv5配套训练数据集、开题报告、中期检查和论文材料。说白了它解决的就是这个东西到底扔哪个桶的问题——用户掏出手机拍一张小程序把图片传到后端模型识别出类别返回对应的垃圾桶颜色和投放提示。适合谁看正在做毕业设计的学生、想入门目标检测的开发者、以及打算把视觉模型落到小程序端的产品同学都能从这套流程里拿到可直接复用的东西。我先把整体思路摆出来再一层层往下拆。很多人一上来就闷头训练模型结果数据集一团糟、类别定义模糊、前后端联调卡壳最后论文写不出来。这套系统的价值不在于模型多先进而在于全链路闭环数据怎么来、模型怎么训、服务怎么部署、小程序怎么接、文档怎么写每一环都有坑也都有相对稳妥的做法。1. 系统整体设计与技术选型拆解1.1 为什么是YOLOv5而不是别的检测模型目标检测模型的选择直接决定了后续训练成本、部署难度和推理速度。我对比过几个主流方案两阶段检测器精度高但速度慢单阶段检测器里YOLO系列在速度和精度之间平衡得最好。选YOLOv5有几个很实际的理由。第一是工程成熟度。YOLOv5的代码结构清晰配置文件用YAML写训练脚本一行命令就能跑对毕业设计这种时间紧、要快速出结果的项目非常友好。第二是模型尺寸可选。它提供n/s/m/l/x五个规格nano版本参数量小推理快适合部署到资源有限的服务器甚至边缘设备如果追求精度可以上m或l。第三是社区资料丰富遇到报错基本都能搜到解决方案这对新手太重要了。这里要说明一点YOLOv5本身是检测模型输出的是边界框加类别。垃圾分类场景里一张图往往只有一个主体物体理论上分类模型也够用。但实际拍摄时画面里可能有多个物品、有背景干扰用检测模型能定位主体位置还能处理一图多物的情况鲁棒性更好。这是我选检测而非纯分类的核心考量。1.2 微信小程序作为前端的合理性前端为什么用微信小程序而不是做个网页或App从使用场景看扔垃圾是随时随地发生的动作用户不可能专门装个App。小程序免安装、扫码即用、调用摄像头方便天然契合这个场景。而且小程序有成熟的图片上传API和网络请求能力跟后端对接很顺。从毕设角度看小程序开发门槛比原生App低WXML加JS的写法上手快云开发还能省掉一部分服务器配置工作。不过要注意小程序对请求域名有白名单限制后端接口必须配置HTTPS域名本地调试时要在开发者工具里勾选不校验合法域名这个后面会细说。1.3 数据集与类别体系的设计逻辑垃圾分类的类别体系各地标准不一样常见的是四分法可回收物、有害垃圾、厨余垃圾湿垃圾、其他垃圾干垃圾。这套系统按四分法设计但具体到物品类别需要拆得更细才能训练。比如可回收物下面有塑料瓶、纸箱、易拉罐、玻璃瓶等厨余垃圾下面有果皮、菜叶、剩饭等。我的做法是先定义细类再映射到大类。模型输出的是细类比如塑料瓶后端根据映射表转成大类可回收物并给出投放提示。这样做的好处是模型学得更聚焦细类之间的视觉差异明显准确率更高同时映射表可以灵活调整万一标准变了改配置就行不用重训模型。数据集来源主要有三块公开数据集筛选、网络图片爬取注意版权和合规、自己拍摄补充。公开数据集质量参差不齐需要人工清洗自己拍摄的图片最贴近真实使用场景建议每个类别至少拍几十张不同角度、不同光照的样本。1.4 整体架构与数据流系统分三层小程序端负责拍照、裁剪、上传、展示结果服务端负责接收图片、调用模型推理、返回类别和提示模型层是训练好的YOLOv5权重通过推理脚本或封装成API供服务端调用。数据流是这样的用户在小程序点拍照图片先压缩小程序有压缩API控制在上传大小限制内通过wx.uploadFile传到服务端接口服务端保存临时文件调用推理模块模型返回检测框和类别服务端把细类映射成大类组装成JSON返回小程序解析后展示垃圾桶颜色、类别名称和投放建议。整个链路要控制响应时间实测下来从上传到返回最好在2秒内否则用户体验会打折。2. 数据集准备与模型训练的核心细节2.1 数据采集与清洗的实操要点数据是模型的地基这一步偷懒后面全是坑。我踩过最深的坑就是类别不平衡——其他垃圾样本一大堆有害垃圾少得可怜训出来的模型对有害垃圾几乎没识别能力。解决办法是按类别配额采集每个细类保证样本量在同一量级差距控制在2倍以内。采集渠道上公开数据集可以拿来打底但一定要人工过一遍剔除标注错误、模糊、重复的图片。自己拍摄时注意多样性不同背景桌面、地面、手持、不同光照白天、晚上、室内灯光、不同角度俯拍、侧拍、不同遮挡程度。我一般每个细类拍80到150张总量控制在几千张的量级对毕设来说够用了。清洗环节要做三件事去重用感知哈希或简单的文件大小加尺寸比对、剔除无效图纯背景、严重模糊、检查标注。标注工具用LabelImg或Labelme都行YOLO格式要求每张图对应一个txt每行是类别id 中心x 中心y 宽 高坐标都归一化到0到1之间。标注时框要贴紧物体边缘别留太多背景也别把物体截断。注意标注类别id必须和data.yaml里的names顺序严格对应错一位整个训练就废了。我见过有人把id写反训了两天才发现血泪教训。2.2 数据集划分与配置文件编写标注完要划分训练集、验证集、测试集常见比例是7:2:1或8:1:1。划分时用脚本随机打乱再分别手动挑避免引入偏差。划分完检查一下每个集合里各类别都有样本别出现某个类只在训练集里。配置文件有两个关键文件。一个是数据集配置data.yaml内容大致是训练集路径、验证集路径、类别数nc、类别名列表names。另一个是模型配置选yolov5s.yaml的话基本不用改主要确认nc和实际类别数一致。这里有个细节如果你用预训练权重nc不一致时加载会报错解决办法是训练时加--weights参数让它自动适配或者手动改模型配置里的nc。# data.yaml 示例结构 train: ../dataset/images/train val: ../dataset/images/val nc: 12 names: [plastic_bottle, carton, can, glass_bottle, battery, bulb, peel, vegetable, leftover, napkin, ceramic, other]类别数12只是举例实际按你的细类数量填。names的顺序就是标注时用的id顺序务必一致。2.3 训练参数的选择与调优思路训练命令本身不复杂关键是参数怎么定。我常用的起手配置是输入尺寸640、batch size根据显存定8G显存大概能跑16、epochs先设100看收敛情况、学习率用默认的0.01配合余弦退火。优化器选SGD或AdamW都行SGD在小数据集上更稳。这里解释几个关键参数背后的逻辑。输入尺寸640是YOLOv5的默认值兼顾精度和速度如果你的物体普遍很小可以提到800但显存和推理时间都会涨。batch size影响梯度稳定性太小震荡大太大显存吃不消一般取能跑动的最大值。epochs不是越多越好要看验证集loss是否还在降早停机制可以加上patience设20左右连续20轮没提升就停。训练过程中盯几个指标训练loss是否稳定下降、验证集mAP是否在涨、有没有过拟合迹象训练loss降但验证loss升。如果过拟合可以加数据增强YOLOv5自带Mosaic、翻转、色彩抖动、加dropout、或者减少模型规模。如果欠拟合检查数据标注质量、增加epochs、换更大模型。我实测下来几千张图、12个类别用yolov5s训100到150轮mAP能到0.85以上对毕设来说完全够看。如果追求更高精度可以上yolov5m但推理会慢一些要权衡。2.4 训练结果评估与模型导出训练完看results.png里的曲线重点看mAP0.5和mAP0.5:0.95。前者是IoU阈值0.5时的平均精度后者更严格。垃圾分类场景物体通常比较完整mAP0.5能到0.85以上算不错。还要看混淆矩阵找出容易混淆的类别对比如纸箱和纸巾可能混玻璃瓶和塑料瓶在反光时可能混针对这些可以补样本再训。模型导出用export.py导出成ONNX格式方便跨平台部署或者直接保留pt权重用Python推理。如果服务端是Python环境直接用torch加载pt最省事。导出ONNX时注意opset版本太新太旧都可能出问题11或12比较稳。3. 服务端推理接口与小程序端实现3.1 推理服务的封装方式服务端我推荐用Flask或FastAPI封装一个HTTP接口轻量够用。核心逻辑是接收上传的图片保存到临时目录调用YOLOv5的推理函数拿到检测结果做类别映射返回JSON。推理部分可以直接调用YOLOv5仓库里的detect.py逻辑或者用torch.hub加载模型自己写推理循环。自己写更灵活能控制预处理和后处理。预处理要把图片resize到模型输入尺寸并归一化后处理要做NMS非极大值抑制去掉重复框再按置信度阈值过滤。# 推理接口核心逻辑示意Flask from flask import Flask, request, jsonify import torch from PIL import Image import io app Flask(__name__) model torch.hub.load(ultralytics/yolov5, custom, pathbest.pt) # 细类到大类的映射表 CATEGORY_MAP { plastic_bottle: (可回收物, #1E90FF), battery: (有害垃圾, #FF0000), peel: (厨余垃圾, #228B22), napkin: (其他垃圾, #808080), # ... 其余类别 } app.route(/predict, methods[POST]) def predict(): file request.files[image] img Image.open(io.BytesIO(file.read())).convert(RGB) results model(img, size640) detections results.pandas().xyxy[0] if detections.empty: return jsonify({code: 1, msg: 未识别到物体}) top detections.sort_values(confidence, ascendingFalse).iloc[0] label top[name] big_cat, color CATEGORY_MAP.get(label, (其他垃圾, #808080)) return jsonify({ code: 0, detail: label, category: big_cat, color: color, confidence: round(float(top[confidence]), 3) }) if __name__ __main__: app.run(host0.0.0.0, port5000)这段代码是示意实际要加异常处理、文件大小限制、临时文件清理。置信度阈值建议设0.4到0.5太低会误报太高会漏报。取置信度最高的检测结果作为主结果如果画面里有多个物体可以返回前几个。3.2 小程序端的页面与交互设计小程序端至少要有两个页面首页拍照/选图入口和结果页展示识别结果。首页放一个大按钮拍照识别点击调wx.chooseImage或直接用camera组件。选完图先预览用户确认后点开始识别触发上传。上传用wx.uploadFile注意几个点一是图片要压缩用wx.compressImage控制质量避免上传超大图二是要显示loading状态网络慢时用户知道在等三是处理失败情况超时或服务端报错要给友好提示别让用户干瞪眼。结果页展示类别名称、所属大类、对应垃圾桶颜色用色块直观呈现、置信度、投放建议文字。颜色映射很关键可回收物蓝色、有害垃圾红色、厨余垃圾绿色、其他垃圾灰色这是通用认知用户一看就懂。// 小程序上传核心逻辑示意 wx.chooseImage({ count: 1, sizeType: [compressed], success(res) { const tempPath res.tempFilePaths[0] wx.showLoading({ title: 识别中... }) wx.uploadFile({ url: https://your-domain.com/predict, filePath: tempPath, name: image, success(uploadRes) { wx.hideLoading() const data JSON.parse(uploadRes.data) if (data.code 0) { // 跳转结果页并传参 wx.navigateTo({ url: /pages/result/result?category${data.category}detail${data.detail}color${encodeURIComponent(data.color)} }) } else { wx.showToast({ title: data.msg || 识别失败, icon: none }) } }, fail() { wx.hideLoading() wx.showToast({ title: 网络异常请重试, icon: none }) } }) } })3.3 前后端联调的常见卡点联调阶段最容易卡在域名和跨域上。小程序要求请求域名在后台配置白名单且必须是HTTPS本地开发时在开发者工具详情-本地设置里勾选不校验合法域名、web-view业务域名、TLS版本以及HTTPS证书就能用http的本地地址调试。上线前必须换成备案过的HTTPS域名。另一个卡点是图片格式和大小。小程序上传的临时文件可能是jpg也可能是png服务端要兼容。大小限制方面小程序单次上传有上限服务端也要设max_content_length超了返回明确错误。还有编码问题返回的JSON里中文要确保UTF-8小程序端JSON.parse前确认拿到的是字符串不是对象。4. 常见问题排查与毕设文档撰写经验4.1 训练与推理阶段的典型故障速查实际做下来问题集中在几个地方我整理成表方便对照。现象可能原因排查与解决训练loss不降学习率过大、标注错误、数据未归一化降学习率到0.001试、抽查标注文件、确认图片路径正确验证mAP很低但训练正常过拟合、验证集分布不同加数据增强、检查验证集是否混入异常样本推理报维度错误输入尺寸与模型不匹配、通道数不对确认图片转RGB三通道、resize到模型输入尺寸小程序上传失败域名未配置、文件超限、证书问题检查白名单、压缩图片、确认HTTPS有效识别结果乱跳置信度阈值过低、NMS参数不当提高conf阈值、调整iou阈值到0.45左右服务端内存暴涨临时文件未清理、模型重复加载用完删临时文件、模型全局加载一次这张表里的每一条我都真实遇到过。印象最深的是服务端内存暴涨一开始每次请求都重新加载模型跑几十次服务就崩了后来把模型加载提到全局问题消失。还有识别结果乱跳是conf阈值设了0.25太低背景里的杂物也被识别提到0.45就稳了。4.2 提升识别准确率的几个实用技巧除了调参还有几个不靠堆算力的办法。第一是测试时增强TTA推理时对图片做翻转、多尺度把结果融合能小幅提升精度代价是推理变慢毕设演示够用。第二是难例挖掘把验证集里识别错的图挑出来补进训练集重训针对性很强。第三是类别映射兜底模型对某些细类没把握时可以按大类返回比如分不清是哪种塑料瓶就统一返回可回收物用户体验反而更好。还有一个容易被忽略的点拍摄引导。小程序端可以提示用户请将物品置于画面中央、避免强反光从源头提升输入质量比后期调模型省事得多。我在结果页加了个重新拍摄按钮引导用户换个角度再试实际使用中这个设计的满意度挺高。4.3 开题报告、中期检查与论文的撰写思路毕设文档这块很多人卡在不知道写什么。开题报告的核心是讲清楚为什么做、做什么、怎么做。研究背景从垃圾分类的现实需求切入国内外现状简述目标检测在垃圾分类上的应用然后明确本系统的目标和创新点比如全链路闭环、小程序落地。技术路线画个流程图把数据、模型、服务、前端串起来。中期检查重点展示进度和阶段性成果。这时候模型应该已经训出第一版能跑通推理小程序有基本页面。文档里放训练曲线、mAP数据、界面截图说明已完成和待完成的部分遇到的技术难点及解决思路。别只报喜适当写点踩坑和调整显得真实。论文结构一般是绪论、相关技术、系统设计、系统实现、实验与结果分析、总结与展望。实验部分要有对比比如不同模型规格的mAP和推理速度对比、不同置信度阈值对准确率的影响用表格和图表呈现。系统实现部分贴关键代码和界面图说明模块职责。总结部分客观写不足比如数据集规模有限、复杂背景下精度待提升这反而是加分项。提示论文里的数据要能自圆其说mAP、准确率、召回率的计算方式要写清楚别直接抄别人的数字。答辩时老师最爱问的就是你这个指标怎么算的。4.4 部署上线与演示的注意事项如果只是毕设演示本地跑服务加开发者工具预览就够了。如果要真正上线服务端得部署到有公网IP的服务器配好HTTPS证书小程序提交审核。审核时注意类目选择工具类或教育类比较合适描述里别夸大功能。演示环节有个小技巧提前准备一批测试图片存在手机里现场网络不稳时可以直接选图识别不至于冷场。另外把服务端的日志开着万一出问题能快速定位。我见过演示时服务没启动、域名证书过期的尴尬场面提前一天完整走一遍流程很有必要。5. 系统扩展与个人实操体会这套系统跑通之后扩展空间其实挺大。比如加个历史记录功能把用户识别过的物品存本地做个统计看哪种垃圾扔得多或者加语音播报识别完直接念出类别对老人更友好再或者做批量识别一张图里多个物品分别框出来给结果。这些都不难属于锦上添花。模型层面可以尝试轻量化把yolov5s换成更小的模型或者做量化让推理更快甚至考虑端侧推理的可能。数据层面持续积累真实场景的图片定期增量训练模型会越用越准。我个人在实际操作中的体会是这类项目七分在数据和工程三分在模型。模型选个成熟的、参数调对基本不会太差真正耗时间的是数据清洗、标注一致性、前后端联调、文档打磨。所以时间分配上别把大头压在调模型上留足时间把链路打通、把文档写扎实。还有一点代码和文档都要有版本管理改一版存一版答辩前回滚也方便。踩过几次坑之后我养成了习惯每完成一个模块就提交一次写清楚改了什么后期排查问题省太多事。
阅读完成 · 觉得有帮助?
咨询建站