共计 3261 个字符,预计需要花费 9 分钟才能阅读完成。
技术背景
工业设备故障诊断的核心挑战往往来自三个方面:数据噪声大、特征维度高以及样本不均衡。传统方法如 SVM 或单一决策树在处理这些问题时表现有限:

- SVM对高维特征和噪声敏感,且核函数选择需要经验
- 决策树 容易过拟合,难以捕捉深层特征关系
CMAE(卷积自编码器)+ 随机森林的组合优势在于:
- 特征提取:CMAE 通过卷积层和 bottleneck 结构(中间层维度压缩)自动学习鲁棒特征表示
- 分类稳健性:随机森林的集成特性有效缓解过拟合,适合处理非平衡数据
- 端到端处理:CMAE 可嵌入标准化预处理层,形成完整特征工程流水线
核心实现
CMAE 特征提取实现
import torch
import torch.nn as nn
class CMAE(nn.Module):
def __init__(self, input_dim=128):
super().__init__()
# 编码器:两个卷积层 +ReLU
self.encoder = nn.Sequential(nn.Conv1d(1, 16, kernel_size=5, stride=2), # 输入通道 1,输出 16
nn.ReLU(),
nn.Conv1d(16, 8, kernel_size=3, stride=2), # 压缩至 8 通道
nn.ReLU())
# 瓶颈层:特征压缩核心
self.bottleneck = nn.Linear(8*30, 32) # 假设时序长度经卷积后剩 30
# 解码器(对称结构)self.decoder = nn.Sequential(nn.Linear(32, 8*30),
nn.Unflatten(1, (8, 30)),
nn.ConvTranspose1d(8, 16, kernel_size=3, stride=2),
nn.ReLU(),
nn.ConvTranspose1d(16, 1, kernel_size=5, stride=2)
)
def forward(self, x):
encoded = self.encoder(x)
encoded = encoded.view(encoded.size(0), -1) # 展平
bottleneck = self.bottleneck(encoded)
decoded = self.decoder(bottleneck)
return bottleneck, decoded # 返回压缩特征和重构结果
关键设计说明:
- Bottleneck 层 强制网络学习压缩表示(32 维),过滤噪声
- 卷积步长 (stride) 逐步降低时序维度
- 输出同时返回压缩特征和重构信号,便于训练监督
随机森林分类器
from sklearn.ensemble import RandomForestClassifier
# 重要参数说明
model = RandomForestClassifier(
n_estimators=200, # 树的数量
max_depth=10, # 防止过拟合
class_weight='balanced', # 自动处理类别不平衡
n_jobs=-1 # 使用所有 CPU 核心
)
特征可视化对比
import matplotlib.pyplot as plt
# 原始特征(假设是 10 维传感器数据)plt.figure(figsize=(12,4))
plt.subplot(121)
plt.title('原始特征')
plt.imshow(raw_features.T, aspect='auto')
# CMAE 提取后的特征(32 维)plt.subplot(122)
plt.title('CMAE 特征')
plt.imshow(cmae_features.T, aspect='auto')
plt.show()
生产级优化
处理类别不平衡
方法 1:SMOTE 过采样
from imblearn.over_sampling import SMOTE
smote = SMOTE(sampling_strategy='minority')
X_res, y_res = smote.fit_resample(X_train, y_train)
方法 2:随机欠采样
from imblearn.under_sampling import RandomUnderSampler
under = RandomUnderSampler(sampling_strategy='majority')
X_res, y_res = under.fit_resample(X_train, y_train)
方法 3:类别权重调整(推荐方案)
# 计算类别权重
from sklearn.utils import class_weight
weights = class_weight.compute_class_weight('balanced',
classes=np.unique(y_train),
y=y_train)
model.set_params(class_weight=dict(enumerate(weights)))
模型持久化方案
Joblib 方案(适合 Python 环境)
from joblib import dump
dump(model, 'model.joblib') # 加载时用 load()
ONNX 方案(跨平台部署)
import onnxruntime as ort
# 转换随机森林
from skl2onnx import convert_sklearn
onnx_model = convert_sklearn(model, 'rf_model.onnx')
# 推理时使用
sess = ort.InferenceSession('rf_model.onnx')
inputs = {'input': X_test.astype(np.float32)}
preds = sess.run(None, inputs)
并发 API 设计
from flask import Flask
import gevent
from gevent import monkey
monkey.patch_all()
app = Flask(__name__)
@app.route('/predict', methods=['POST'])
def predict():
data = request.json['features']
# 异步处理请求
return jsonify({'prediction': model.predict([data])[0]})
if __name__ == '__main__':
# 使用 gevent 的 WSGI 服务器
from gevent.pywsgi import WSGIServer
http_server = WSGIServer(('0.0.0.0', 5000), app)
http_server.serve_forever()
避坑指南
- CMAE 学习率震荡:
- 使用学习率预热(如前 5 个 epoch 从 1e- 5 线性增加到 1e-3)
-
添加梯度裁剪(
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)) -
随机森林特征重要性误判:
- 高基数特征(如 ID 类)可能被误认为重要
-
解决方案:先用 CMAE 降维,或手动过滤无关特征
-
模型漂移监测:
- 记录每日预测结果的分布变化(KL 散度检测)
- 设置预警阈值:当验证集 F1 下降 5% 时触发重训练
延伸思考
在线学习系统设计
# 增量更新随机森林的部分实现
model.n_estimators += 10 # 增加新树
new_trees = RandomForestClassifier(n_estimators=10)
new_trees.fit(new_data, new_labels)
# 将新树合并到原模型(需自定义实现)
与 LSTM+Attention 对比
| 方案 | 适用场景 | 训练速度 | 可解释性 |
|---|---|---|---|
| CMAE+ 随机森林 | 中等长度时序 / 高噪声数据 | 快 | 中等 |
| LSTM+Attention | 长序列依赖 / 需要时序解释 | 慢 | 较高 |
实际测试数据(某轴承故障数据集):
- CMAE+RF:F1=0.92,推理延迟 8ms/ 样本
- LSTM+Attention:F1=0.94,延迟 35ms/ 样本
选择建议:对实时性要求高的场景优先 CMAE 方案,需要捕捉长期依赖时用 LSTM。
正文完
发表至: 未分类
四天前
