尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

基于Python的多模态垃圾分类系统:双塔融合与工程实现

发布时间:2026/9/25 3:46:08

资讯中心
01
ARTICLE

基于Python的多模态垃圾分类系统:双塔融合与工程实现

基于Python的多模态垃圾分类系统:双塔融合与工程实现
简介基于Python实现的多模态垃圾分类系统是一套面向高校课程设计及毕业设计的完整工程资源适合需要完成垃圾分类相关项目的计算机、环境类专业学生。系统融合图像与文本两种模态信息支持上传垃圾图片或输入名称描述对可回收物、有害垃圾、厨余垃圾与其他垃圾进行智能判别并涵盖数据采集、预处理、特征提取、模型分类与用户界面等完整流程。压缩包共1282个文件约77.96MB以621个Python源码文件py和544个编译缓存pyc为核心辅以32个proto模型配置文件、13个txt说明文档及若干可执行工具便于直接运行与二次开发。资源内附课程设计报告和项目文档从需求分析、系统设计到实现细节均有完整阐述可帮助理解多模态分类原理、把握模型训练与推理的关键步骤并快速搭建可演示的完整系统。已有148人学习适合作为课设参考或项目起步模板。1. 多模态垃圾分类系统在课设里到底解决什么问题“基于 Python 实现多模态垃圾分类系统”听起来像把图像分类和自然语言处理硬凑在一起但真正动手做过课设就知道单靠图像分类做垃圾分类上限非常低。一张沾了油渍的塑料饭盒和一张白色纸团在纯视觉模型眼里可能长得差不多用户只要补一句“这是脏的外卖盒”结果立刻不同。这个方案的本质是用“图像特征 文本描述特征”做双塔融合解决纯视觉分类在脏污、遮挡、材质相近场景下的歧义。它特别适合课程设计、毕业设计以及想往多模态方向入门的新手——代码量可控、能出指标、有网页演示又不必一上来就接触多模态大模型的全部复杂度。2. 从图像分类到多模态先把融合思路和选型定下来2.1 为什么垃圾分类卡在纯图像分类的极限上垃圾图片分类和普通物体分类有一个明显区别垃圾的形态、脏污程度、拍摄环境方差极大。同一个矿泉水瓶在明亮桌面上的完整特写和揉扁后丢在垃圾桶里沾着汤汁的照片对分类器来说几乎是两种不同的输入。纯图像分类模型在 TrashNet 这类相对干净的数据集上能跑到 90% 以上一遇到真实拍摄场景就明显下滑这几乎是所有做课设的人第一次看到结果时的共同感受。这不是模型能力不够而是任务本身自带视觉歧义。白色薄塑料袋和白色纸巾、破碎的陶瓷碗和玻璃碎片仅靠像素级特征很难区分。更重要的是垃圾分类在很多情况下是“功能属性”而不是“物理属性”干净的纸盒可回收沾了食物残渣的纸盒就是其他垃圾。外观相近、功能不同这两者之间的矛盾纯图像模型绕不过去。多模态方案直接把上限抬高图像分支负责“看到什么”文本分支负责“从哪个维度理解”。用户输入“干净的纸箱”或“湿纸巾”等于告诉模型忽略外观上的相似性把判别依据从像素转移到语义。对课设阶段来说这是投入产出比很高的选择——不需要造大模型在原有两个轻量编码器上做一次特征拼接精度就能肉眼可见地提升。2.2 双塔结构的选型逻辑图像分支、文本分支与融合方式常见做法是让两个编码器各自处理一种模态在中间层完成融合。图像分支直接加载 ImageNet 预训练的 ResNet18 或 ResNet34去掉最后的全连接层把池化后的 512 维特征向量取出来。垃圾分类数据集本身不大通常只有几百到几千张图片从零训练 ResNet 必然过拟合冻结主干、只训练最后两层和融合层是更稳的方案。文本分支的选择空间更大。如果数据量很小每个类别只有几句描述用预训练句子向量模型就够如果希望体现代码水平可以用一个小型 Transformer encoder把描述文本编码成 256 维向量。课设阶段我建议优先用预训练中文句子向量模型原因很简单短文本从零训练 encoder 很难收敛预训练的语义空间已经能区分“透明塑料瓶”和“玻璃瓶”。融合方式有三档可选。课设阶段首选 concat简单、可控、容易画进论文结构图有余力再尝试 cross-attention那才是论文里常说的“多模态融合”的常规操作。融合方式实现复杂度效果适合场景concat 拼接后过全连接低中课设入门、复现稳定双分支加权求和低中高类别少、文本特征强于图像特征cross-attention 融合中高高想冲高指标、答辩有亮点注意 concat 这个看似“土”的融合方式实际效果并不差。图像特征和文本特征拼接后网络学到的其实是“两种模态哪个更可信”的权重在类别歧义不太离谱的数据集上已经够用。cross-attention 的优势在长文本、复杂语义上更明显而垃圾分类的描述往往只有一句话权重分配的收益有限。课设阶段也不建议直接上多模态大模型CLIP 之类零样本能力虽强但部署体积大、依赖版本复杂被追问细节时很难收场轻量双塔反而每一层都能解释。2.3 多模态垃圾分类系统的整体模块划分一次课设级别的多模态垃圾分类系统最少需要四个模块。数据模块负责图片和文本的对齐与格式统一这也是多模态特征统一处理最关键的一步模型模块定义双塔结构和融合层训练模块处理损失、优化器和指标记录展示模块把推理结果落到网页上方便答辩现场演示。四个模块分开写后续替换任何一个部分都不牵动全局。代码组织上我习惯把类别配置写进一个文本文件而不是硬编码在模型里因为课设中途调整类别非常常见。常见做法是 categories.txt 一行一个类别同时给每个类别预置几条描述模板。“多模态特征文件”这一步放在数据模块中训练前先统一抽取一次图像特征和文本特征缓存到 npy 文件跑实验时不需要反复读原图能省下一半训练时间。实践中的细节是特征缓存后融合层和分类层可以单独调参图像和文本两个预训练编码器基本固定超参数搜索从“两个网络一起调”变成“只调分类头”对新手友好很多。做完这一步整个系统结构就清楚了数据流是“图片路径 文本描述 - 两个编码器 - 特征拼接 - 分类头 - 四分类概率”模型代码和项目报告的框图能一一对应。3. 搭建最小可运行的多模态垃圾分类系统从数据到训练到推理3.1 环境准备与最小依赖列表先把 Python 环境锁死如果你是 python 入门阶段建议直接用 Anaconda 创建独立环境别把系统 Python 弄乱。VSCode 里配置好解释器后在项目根目录建 requirements.txttorch2.0.0 torchvision0.15.0 transformers4.30.0 numpy1.24.0 pandas1.5.0 pillow9.5.0 flask2.3.0 scikit-learn1.2.0 matplotlib3.7.0安装命令conda create -n gcls python3.10 conda activate gcls pip install -r requirements.txt说明torch 和 torchvision 的版本必须配套否则 import 阶段就报错transformers 负责加载预训练文本编码器。这套依赖没有 GPU 也能跑完整个流程训练时间会增加但不至于跑不动。3.2 把图片和文本描述组织成数据集目录结构与 CSV 对齐先准备数据目录data/ categories.txt images/ recyclable/001.jpg harmful/002.jpg kitchen/003.jpg other/004.jpg texts.csvcategories.txt 每行一个类别名。公开数据集可以选 TrashNet 或华为垃圾分类数据集也可以从网上搜图自己建一个小集子每类 100~200 张就够课设使用。texts.csv 把图片路径、描述文本和类别对齐image_path,text,category images/recyclable/001.jpg,一个干净的塑料饮料瓶,recyclable images/kitchen/003.jpg,剩饭剩菜和骨头,kitchen images/other/004.jpg,沾了油污的纸巾,other对应的 Dataset 代码如下# dataset.py import pandas as pd from PIL import Image from torch.utils.data import Dataset from torchvision import transforms class GarbageDataset(Dataset): def __init__(self, csv_path, label2id, img_size224): self.df pd.read_csv(csv_path) self.label2id label2id self.img_transform transforms.Compose([ transforms.Resize((img_size, img_size)), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]), ]) def __len__(self): return len(self.df) def __getitem__(self, idx): row self.df.iloc[idx] image Image.open(row[image_path]).convert(RGB) text row[text] label self.label2id[row[category]] return self.img_transform(image), text, label说明Resize 到 224×224Normalize 参数必须用 ImageNet 的均值方差三条缺一条预训练权重都会“不认识”你的图片。文本字段以字符串原样返回由模型内部的 tokenizer 处理Dataset 里不做编码这是为了让数据模块保持简单后续替换文本编码器不影响数据层。3.3 用 PyTorch 实现双塔融合模型冻结编码器只训融合层模型定义代码如下# model.py import torch import torch.nn as nn from torchvision import models from transformers import AutoTokenizer, AutoModel class MultiModalGarbageModel(nn.Module): def __init__(self, num_classes, text_feature_dim256, image_feature_dim512, fusion_dim256): super().__init__() # 图像分支ResNet18 去掉分类头返回 512 维特征 backbone models.resnet18(weightsmodels.ResNet18_Weights.IMAGENET1K_V1) self.image_encoder nn.Sequential(*list(backbone.children())[:-1]) for p in self.image_encoder.parameters(): p.requires_grad False # 文本分支预训练中文句向量模型 self.text_tokenizer AutoTokenizer.from_pretrained( uer/sbert-base-chinese-nli) self.text_encoder AutoModel.from_pretrained( uer/sbert-base-chinese-nli) for p in self.text_encoder.parameters(): p.requires_grad False self.text_proj nn.Sequential( nn.Linear(768, text_feature_dim), nn.ReLU(), ) # 融合层与分类头 self.fusion nn.Sequential( nn.Linear(image_feature_dim text_feature_dim, fusion_dim), nn.ReLU(), nn.Dropout(0.3), ) self.classifier nn.Linear(fusion_dim, num_classes) def forward(self, images, text): with torch.no_grad(): img_feat self.image_encoder(images).flatten(1) text_out self.text_encoder( **self.text_tokenizer( text, paddingTrue, truncationTrue, max_length32, return_tensorspt) ).last_hidden_state[:, 0, :] text_out text_out.to(images.device) text_feat self.text_proj(text_out) feat torch.cat([img_feat, text_feat], dim1) return self.classifier(self.fusion(feat))说明图像和文本两个编码器加载后立即冻结只有 text_proj、fusion、classifier 三层参与训练参数量很小CPU 也能在合理时间收敛。text_out 显式搬到 images 所在设备避免 GPU 训练时报 device mismatch。多模态模型代码复现的套路在这里体现得很完整两个编码器抽特征融合层降维交互分类头输出概率整体结构最容易理解和改造成其他多模态任务。3.4 训练参数详解与三种必调参数训练脚本# train.py import torch import torch.nn as nn from torch.utils.data import DataLoader def train(model, loader, epochs15, lr1e-3): device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device) optimizer torch.optim.Adam( filter(lambda p: p.requires_grad, model.parameters()), lrlr) criterion nn.CrossEntropyLoss() for epoch in range(epochs): model.train() total_loss, total_correct, total 0, 0, 0 for images, text, label in loader: images, label images.to(device), label.to(device) optimizer.zero_grad() logits model(images, text) loss criterion(logits, label) loss.backward() optimizer.step() total_loss loss.item() total_correct (logits.argmax(1) label).sum().item() total len(label) print(fepoch {epoch1}/{epochs} floss{total_loss/len(loader):.4f} facc{total_correct/total:.4f})训练时最值得调三个参数。第一是学习率。预训练 backbone 被冻结参与训练的只有融合层和分类头lr1e-3 是稳妥起点如果 loss 震荡降到 3e-4。如果后续解冻部分 backbone 微调图像分支学习率要单独放到 1e-5否则预训练权重很快被破坏。第二是 batch_size。数据量小batch_size 建议 16 或 32ResNet18 输入 224×22432 张的 batch 在 8G 显存上没问题。没有 GPU 时把 batch_size 降到 8DataLoader 的 num_workers 设成 4 左右Windows 上超过 CPU 核心数反而会卡。第三是文本 max_length。中文短描述一般 10~20 字max_length32 足够。太短会截断语义太长会让 padding 占绝大多数位置文本编码器的注意力被空 token 稀释。训练完成后保存权重torch.save(model.state_dict(), multimodal_garbage.pt)3.5 推理脚本与结果可视化一张图加一句话输出四分类概率推理脚本# predict.py import torch from PIL import Image from model import MultiModalGarbageModel from preprocessing import get_img_transform model MultiModalGarbageModel(num_classes4) model.load_state_dict(torch.load(multimodal_garbage.pt, map_locationcpu)) model.eval() image Image.open(test.jpg).convert(RGB) text 透明的矿泉水瓶 transform get_img_transform(img_size224) with torch.no_grad(): logits model(transform(image).unsqueeze(0), [text]) prob torch.softmax(logits, dim1) print(prob)这里引用了 preprocessing.py 里的 get_img_transform这是刻意为之训练和推理共用同一套预处理逻辑避免两边各写一份后不一致。推理输出是四分类概率取 argmax 就是最终类别。如果后续接 Flask 网页只需要把这个函数包成 POST 接口前端传图片和描述文本后端返回 JSON 概率数组。4. 避坑多模态垃圾分类系统最常见的 5 个翻车现场4.1 训练预处理和推理预处理不是同一份代码现象训练准确率 92%部署到网页后用户上传一张图结果错得乱七八糟。原因训练 pipeline 里走了 Resize、ToTensor、Normalize推理脚本里只调用了 Resize 和 ToTensor忘了 Normalize。预训练模型对输入均值方差极敏感输入分布不对输出概率完全失去意义。解决把 transforms.Compose 定义在独立的 preprocessing.py 里train.py 和 predict.py 都从 preprocessing import get_img_transform。一遍实现、两处使用永远不要在两个文件里各写一份。4.2 文本分支变成“类别名记忆器”现象训练集里文本是模板生成的“一个透明的塑料瓶”测试时换一句“喝完的矿泉水瓶”模型概率明显下降或者改文本描述、输出结果完全不变文本分支对图像分支没有任何修正作用。原因模板写得太死文本编码器实际上记住了类别关键词而不是理解语义。测试阶段用户输入的自然语言和训练模板分布不一致文本特征自然泛化不了。解决数据增广阶段把描述写成多样式每类准备 8~10 条不同句式例如“透明的塑料饮料瓶”“PET 材质、可以压扁的瓶子”“矿泉水喝完后的空瓶”。同时打印 text_feature 对应 loss 的梯度是否为非零如果一直是零说明文本分支没参与训练优先查模型参数冻结和网络连接。4.3 类别不均衡导致整体准确率高、有害垃圾全废现象可回收垃圾 1000 张有害垃圾 80 张训练出的模型整体准确率 94%但有害垃圾召回率只有 30%答辩时被问住。原因交叉熵损失在多数类主导下少数类梯度被淹没。解决给损失函数加类别权重权重按“总样本数 / (类别数 × 每类样本数)”计算或用 sklearn.utils.class_weight.compute_class_weight 算好后传给 CrossEntropyLoss(weight...)。评估时不要只报 accuracy逐类报 F1-score报告里才能看出不均衡问题的处理确实有效。提示类别权重加不加在四分类不均衡数据集上结果差异非常大这是课设里最容易白拿的分数点。4.4 双塔收敛速度不一致训练白跑一半现象前几个 epoch 图像分支已经把 loss 拉得很低文本分支还没学出区分度后程 loss 不再下降训练 30 个 epoch 和 15 个 epoch 的结果几乎一样。原因图像特征 512 维带有强视觉先验文本投影层从零开始随机初始化两者收敛速度天然不同。解决把训练拆成两阶段前 5 个 epoch 只用拼接特征训练分类头之后再解冻 text_proj用更低的学习率 1e-4 继续训练。我实际操作中还给图像侧加了一个 LayerNorm强制两个分支的特征尺度对齐收敛明显稳定。注意这里只解冻 text_proj不碰预训练文本编码器否则短文本数据很容易过拟合。4.5 用户拍图的背景和训练集差异太大现象训练集都是单一背景的俯拍图实际使用时用户拍的是桌上的垃圾桶画面里还有别的物体模型把背景也算进特征识别率骤降。原因模型学到的是场景信息而非物体本身训练集背景太干净泛化不够。解决训练阶段对图像做 RandomResizedCrop 和 RandomHorizontalFlip模拟多变构图推理阶段在网页端提示用户把垃圾放在画面中心再拍摄。如果课设要求再高一点可以加一个显著性裁剪步骤先用目标检测把垃圾区域框出来裁完再走分类这部分作为进阶亮点写进项目文档。5. 把源码变成能答辩的项目文档组织、验证方法与汇报技巧5.1 报告结构要与源码目录一一对应标题带了“源码 课设报告 项目文档”说明交付物不止代码。报告建议按六章写需求分析与目标、相关技术介绍、系统设计、系统实现、实验结果与分析、总结与展望。源码目录按 data/、models/、preprocess/、web/、docs/ 划分README 里写清安装、训练、推理三步命令。答辩老师看的是图表和结构不是长篇代码——每个模块配一张类图或流程图说明数据怎么流动就足够了。5.2 除了准确率答辩还要看的两个指标多模态系统最好同时报告类别 F1-score 和混淆矩阵。F1 能证明类别不均衡处理有效混淆矩阵能定位互相干扰的类别比如“其他垃圾”和“厨余垃圾”经常混淆你可以在报告里写“加入文本描述后混淆率下降 X 个百分点”这句话就是答辩得分的点。再把 loss 曲线和 accuracy 曲线画在同一张双 y 轴图里能直观说明文本分支参与训练后收敛过程稳定比单独贴一堆训练日志有说服力得多。5.3 从课设到作品集三个低成本进阶方向第一个是把模型导出为 ONNX用 CPU 做实时推理。torch.onnx.export 加固定输入尺寸即可网页端响应速度会明显提升这也是简历上能写的一句话。第二个是用 EasyOCR 识别包装上的文字来自动生成文本描述用户只传图不输字这才是更完整的“多模态”闭环代价是需要额外处理 OCR 置信度低的情况。第三个是当 softmax 最大概率低于 0.7 时前端提示用户补充描述这个功能代码量不大却是“能分类”和“可用系统”之间最明显的差别。我自己的习惯是每完成一个版本就重开一个干净的 conda 环境按 README 从零走一遍安装、训练、推理和网页演示把依赖缺失、路径写死、漏传权重文件这类问题提前暴露掉。能按文档复现的课设才敢放进作品集。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。