1. 项目背景与核心价值
垃圾分类一直是城市管理和环境保护的重要课题。传统的人工分类方式效率低下且成本高昂,而基于机器学习的自动化分类系统能够显著提升分类准确率和处理速度。这个项目实现了从数据采集到模型部署的完整流程,特别针对厨余垃圾和可回收垃圾这两类容易混淆的垃圾进行了优化。
在实际应用中,我们发现可回收垃圾的识别准确率往往低于厨余垃圾。这主要是因为:
- 可回收垃圾的形状、材质差异较大(如纸张、塑料、金属等)
- 厨余垃圾通常具有更统一的视觉特征(如食物残渣、有机物质)
- 数据集中的可回收垃圾样本虽然数量相当,但内部多样性更高
提示:项目特别采用了类别权重调整策略,给可回收垃圾分配了2倍权重,这在后续模型训练中显著提升了可回收垃圾的识别率。
2. 系统架构与技术选型
2.1 整体架构设计
系统采用经典的三层架构:
- 数据层:存储原始图像和预处理后的数据
- 算法层:包含7种机器学习模型的训练和评估
- 应用层:基于Flask的Web交互界面
code复制项目目录结构详解:
garbage-classification/
├── data/ # 数据存储
│ ├── raw/ # 原始图像
│ └── processed/ # 预处理后的图像
├── models/ # 训练好的模型
│ ├── svm_model.pkl # SVM模型
│ └── rf_model.pkl # 随机森林模型
├── static/ # 静态资源
├── templates/ # HTML模板
├── app.py # Flask应用入口
└── train.py # 模型训练脚本
2.2 算法选型考量
我们选择了7种具有代表性的算法进行对比:
| 算法类型 | 代表算法 | 选用理由 | 适用场景 |
|---|---|---|---|
| 深度学习 | CNN | 图像分类SOTA | 大数据量 |
| 传统神经网络 | MLP | 基准对比 | 小数据量 |
| 集成学习 | 随机森林 | 高准确率 | 中等数据量 |
| 核方法 | SVM | 小样本优势 | 特征明显 |
| 距离度量 | KNN | 简单直观 | 快速原型 |
| 决策树 | CART | 可解释性强 | 规则提取 |
| 线性模型 | 逻辑回归 | 性能基准 | 线性可分 |
特别说明:最终选择SVM和随机森林作为生产环境模型,因为:
- 我们的数据集规模中等(约9000张图片)
- 需要平衡准确率和推理速度
- 可回收垃圾识别需要更好的泛化能力
3. 数据准备与预处理
3.1 数据集构建
我们收集了9031张垃圾图像,按照7:3的比例划分为训练集和测试集。数据采集时特别注意了:
- 光照条件多样性(室内/室外/不同时段)
- 拍摄角度多样性(俯视/平视/斜视)
- 背景复杂度控制(纯色背景/复杂背景)
数据集标注规则:
- 文件名不含"O-":厨余垃圾(标签0)
- 文件名含"O-":可回收垃圾(标签1)
3.2 图像预处理流程
完整的预处理pipeline如下:
python复制def preprocess_image(img):
# 1. 尺寸标准化
img = cv2.resize(img, (150, 150))
# 2. 亮度增强(解决背光问题)
img = cv2.convertScaleAbs(img, alpha=1.5, beta=0)
# 3. 去噪处理
img = cv2.GaussianBlur(img, (5,5), 0)
# 4. 色彩空间转换
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 5. 归一化
img = img.astype(np.float32) / 255.0
return img
关键参数选择依据:
- 150×150分辨率:平衡信息保留和计算效率
- alpha=1.5:通过网格搜索确定的最佳亮度增强系数
- 5×5高斯核:有效消除噪声同时保留边缘信息
3.3 数据增强策略
为提升模型泛化能力,我们实施了以下增强策略:
- 随机旋转(-15°到+15°)
- 水平/垂直翻转(概率0.3)
- 随机亮度调整(±20%)
- 添加高斯噪声(σ=0.01)
注意:测试集不做任何数据增强,确保评估结果反映真实性能。
4. 模型训练与优化
4.1 七种算法实现细节
4.1.1 CNN网络架构
python复制model = Sequential([
Conv2D(32, (3,3), activation='relu', input_shape=(150,150,3)),
MaxPooling2D(2,2),
Conv2D(64, (3,3), activation='relu'),
MaxPooling2D(2,2),
Conv2D(128, (3,3), activation='relu'),
MaxPooling2D(2,2),
Flatten(),
Dense(512, activation='relu'),
Dropout(0.5),
Dense(1, activation='sigmoid')
])
训练配置:
- 优化器:Adam(lr=0.0001)
- 损失函数:binary_crossentropy
- 批次大小:32
- 训练轮次:15
4.1.2 随机森林优化
python复制rf = RandomForestClassifier(
n_estimators=500,
max_depth=30,
min_samples_split=2,
class_weight={0:1, 1:2}, # 关键参数
n_jobs=-1,
random_state=42
)
参数优化过程:
- 初始设置n_estimators=100,逐步增加到500
- 通过网格搜索确定最佳max_depth
- 类别权重1:2显著提升可回收垃圾召回率
4.2 类别不平衡处理
我们对比了三种处理方案:
| 方法 | 准确率 | 召回率(可回收) | 训练时间 |
|---|---|---|---|
| 不处理 | 0.86 | 0.72 | - |
| 过采样 | 0.84 | 0.81 | 较长 |
| 类别权重 | 0.87 | 0.83 | 短 |
| SMOTE | 0.85 | 0.79 | 很长 |
最终选择类别权重调整因为:
- 计算效率最高
- 不需要修改原始数据分布
- 与模型原生集成,无需额外步骤
4.3 模型评估指标
我们采用综合评估策略:
-
基础指标:
- 准确率:(TP+TN)/(P+N)
- 精确率:TP/(TP+FP)
- 召回率:TP/(TP+FN)
- F1分数:2*(精确率*召回率)/(精确率+召回率)
-
可视化工具:
- 混淆矩阵
- ROC曲线
- PR曲线
-
业务指标:
- 可回收垃圾误判率
- 厨余垃圾误判率
- 平均推理时间
5. Web系统实现
5.1 Flask应用架构
python复制# app.py核心结构
app = Flask(__name__)
@app.route('/', methods=['GET'])
def index():
return render_template('index.html')
@app.route('/predict', methods=['POST'])
def predict():
# 1. 接收上传图片
file = request.files['file']
# 2. 预处理
img = preprocess_image(file)
# 3. 模型预测
svm_pred = svm_model.predict(img)
rf_pred = rf_model.predict(img)
# 4. 返回结果
return jsonify({
'svm': svm_pred,
'rf': rf_pred
})
5.2 前端交互设计
关键功能点:
- 拖拽上传区域
- 实时预览功能
- 双模型结果对比展示
- 置信度可视化
- 历史记录查询
html复制<!-- 核心UI组件 -->
<div class="upload-area" id="dropZone">
<input type="file" id="fileInput" accept="image/*">
<div class="preview" id="imagePreview"></div>
</div>
<div class="results">
<div class="model-result" id="svmResult">
<h3>SVM预测结果</h3>
<div class="confidence-bar"></div>
</div>
<div class="model-result" id="rfResult">
<h3>随机森林预测结果</h3>
<div class="confidence-bar"></div>
</div>
</div>
5.3 性能优化技巧
-
模型加载优化:
python复制# 使用joblib并行加载 svm_model = joblib.load('models/svm_model.pkl') rf_model = joblib.load('models/rf_model.pkl') -
图片处理优化:
- 使用OpenCV的imdecode直接处理上传流
- 启用多线程预处理
-
缓存策略:
- 模型预测结果缓存5分钟
- 使用Redis存储高频查询结果
6. 部署与运维
6.1 生产环境部署
推荐部署方案:
-
硬件配置:
- CPU:4核以上
- 内存:8GB+
- GPU:非必需但推荐(加速CNN)
-
软件环境:
bash复制# 使用conda创建环境 conda create -n garbage python=3.8 conda install -c conda-forge scikit-learn opencv flask gunicorn -
服务化部署:
bash复制# 使用gunicorn启动 gunicorn -w 4 -b :5000 app:app
6.2 性能监控
建议监控指标:
- API响应时间(P99 < 500ms)
- 模型预测准确率(每日统计)
- 系统负载(CPU/内存使用率)
- 垃圾类别分布变化
6.3 模型迭代策略
-
持续训练:
- 每周收集新数据
- 增量训练现有模型
-
A/B测试:
- 新模型先服务5%流量
- 逐步扩大范围
-
反馈闭环:
- 用户纠错功能
- 可疑样本人工审核
7. 常见问题排查
7.1 训练阶段问题
问题1:可回收垃圾识别率低
- 检查类别权重设置
- 增加可回收垃圾样本多样性
- 尝试不同的特征提取方法
问题2:模型过拟合
- 增加数据增强
- 添加Dropout层(CNN)
- 调整max_depth参数(树模型)
7.2 部署阶段问题
问题1:预测速度慢
- 优化特征提取流程
- 使用模型量化技术
- 启用批处理预测
问题2:内存泄漏
- 定期重启服务
- 使用--preload参数(gunicorn)
- 监控内存增长
7.3 业务逻辑问题
问题1:未知类别处理
python复制# 置信度阈值策略
if max_prob < 0.3:
return "其他垃圾"
问题2:多标签支持
- 修改模型输出为多分类
- 使用sigmoid替代softmax
- 调整损失函数
8. 项目扩展方向
-
多类别扩展:
- 添加有害垃圾类别
- 增加可回收垃圾细分类(塑料/纸张/金属)
-
移动端适配:
- 开发React Native应用
- 使用TensorFlow Lite部署
-
硬件集成:
- 对接智能垃圾桶
- 开发嵌入式版本
-
算法升级:
- 尝试Vision Transformer
- 引入半监督学习
在实际部署中,我们发现模型在以下场景表现最佳:
- 单个物品清晰拍摄(准确率92%+)
- 白色背景环境(减少干扰)
- 正常光照条件(避免过暗/过曝)
对于复杂场景(如混合垃圾),建议:
- 先进行物理分离
- 多角度拍摄
- 综合多个模型预测结果
