
数据不够怎么办小样本下的预测性维护建模技巧说实话做预测性维护最怕的不是模型调参不是选什么框架而是数据不够。去年Q3我们接了一个江苏做精密齿轮箱的工厂项目。对方有6台关键设备正常运行了3年采集的振动数据大概也就200万条——听起来不少对吧但故障样本呢7条。就7条。其中3条还是同一个轴承在不同阶段的重复记录。你让深度学习去啃这7条样本纯属搞笑。但甲方要的是能跑起来的模型不是等你们再攒两年数据。所以那段时间我们团队被逼着研究了一套小样本建模的路子今天把这些实战经验摊开来聊。一、先搞清楚你的不够是哪种不够很多人一说数据不够就急着上数据增强其实得先分类。我见过的场景大概分三种第一种总量够但类别极度不平衡。比如齿轮箱项目200万条正常数据7条故障。这种其实好办后面要说的SMOTE和代价敏感学习就能解决。第二种总量本身就少。比如新上线的高端设备运行才3个月总共就5万条数据其中故障1条。这种最难搞得靠迁移学习或者预训练模型。第三种标注不够。原始振动信号一大堆但没人标过哪些是故障、故障类型是什么。这种得先从半监督或者主动学习入手。我们那个齿轮箱项目其实是第一种第二种的混合体。总量看着还行但故障样本稀缺到离谱。二、SMOTE不是万能药但确实管用先说最基础的——SMOTESynthetic Minority Over-sampling Technique。很多人看不起SMOTE觉得过采样嘛老生常谈。但说实话在工业场景里SMOTE 一个调得好的随机森林效果经常比瞎折腾的深度学习强。我们在齿轮箱项目上用的不是原版SMOTE而是Borderline-SMOTE。原版SMOTE是在所有少数类样本周围插值但Borderline-SMOTE只对那些靠近决策边界的少数类样本做增强——说白了就是只给模棱两可的样本加戏远离边界的样本不动。代码长这样用的是imbalanced-learn 0.12.0from imblearn.over_sampling import BorderlineSMOTE from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import StratifiedKFold import numpy as np # X_train: 振动特征 (时域统计量 FFT频带能量) # y_train: 0正常, 1内圈故障, 2外圈故障, 3滚动体故障 # 原始分布: 正常 19993条, 故障合计 7条 print(f增强前: {np.bincount(y_train)}) # 输出: [19993, 2, 3, 2] # Borderline-SMOTE, 只过采样到 1:10 的比例不是1:1 # 1:1 在工业场景里容易过拟合1:10 更稳 bsmote BorderlineSMOTE( sampling_strategy{1: 500, 2: 500, 3: 500}, # 故障类过采样到500条 k_neighbors3, # 邻居数设小一点样本太少了 random_state42, kindborderline-1 # borderline-1 比 borderline-2 更保守 ) X_res, y_res bsmote.fit_resample(X_train, y_train) print(f增强后: {np.bincount(y_res)}) # 输出: [19993, 500, 500, 500] # 用随机森林不是XGBoost——小样本下XGBoost容易过拟合 clf RandomForestClassifier( n_estimators200, max_depth8, # 限制深度防止过拟合 min_samples_leaf10, class_weightbalanced_subsample, # 内置的代价敏感学习 random_state42 ) # 5折分层交叉验证必须分层否则某折可能全是正常样本 skf StratifiedKFold(n_splits5, shuffleTrue, random_state42)踩坑提醒SMOTE 一定要在训练集上做千万别在验证集或者测试集上过采样。我见过有人把整个数据集过采样完再划分那评估指标全是假的能到99%但上线就崩。三、数据增强给振动信号加料SMOTE 是在特征空间做插值但振动信号本身也可以做增强。我们在另一个项目里2024年5月给一家做数控机床的台企做主轴健康监测试了几种信号层面的增强方法效果最好的有两个Jitter加高斯噪声和Magnitude Warping幅度扭曲。import numpy as np def jitter(signal, sigma0.03): 给信号加高斯噪声sigma 控制噪声强度 noise np.random.normal(0, sigma, signal.shape) return signal noise def magnitude_warp(signal, sigma0.1, num_knots4): 幅度扭曲用随机样条曲线扭曲信号幅度 from scipy.interpolate import CubicSpline orig_steps np.arange(signal.shape[0]) random_warps np.random.normal(1.0, sigma, (num_knots 2,)) knot_points np.linspace(0, signal.shape[0] - 1, numnum_knots 2) cs CubicSpline(knot_points, random_warps) warped cs(orig_steps) return signal * warped # 一条原始振动信号采样率 12kHz长度 2048 点 original vibration_signal # shape: (2048,) # 增强出 5 条新样本 augmented [] for _ in range(5): aug jitter(original, sigma0.02) aug magnitude_warp(aug, sigma0.08) augmented.append(aug)注意这里有个细节sigma 不能太大。我们一开始设了 0.1增强出来的信号看着跟原信号差很多模型学不到东西。后来降到 0.02-0.03效果反而好。说白了就是增强要像不能太离谱。更狠的是我们把信号增强和 SMOTE 结合用——先对原始故障信号做5倍增强再提取特征最后用 Borderline-SMOTE 在特征空间二次增强。故障样本从7条变成了35条信号再变成1500条特征向量。随机森林的F1-score从0.31提到了0.84。四、迁移学习借别人的数据练自己的模型如果数据真的少到SMOTE都救不了那就得上迁移学习了。2024年8月我们给一个做航空发动机叶片检测的军工项目做支持。对方的数据涉密不能外传但训练样本只有12条故障记录。我们用的是预训练模型 领域微调的路子。具体来说先用公开的轴承故障数据集CWRU凯斯西储大学那个训练一个基础模型然后用客户的少量数据做微调。这里有个关键决策冻结前几层只微调最后2-3层。import torch import torch.nn as nn from torchvision.models import resnet18 # 把1D振动信号转成2D时频图STFT然后喂给ResNet # 这是工业界常用的曲线救国方法 # 加载在CWRU数据集上预训练的模型 pretrained torch.load(resnet18_cwru_stft.pth) model resnet18(pretrainedFalse) model.load_state_dict(pretrained) # 冻结前3层layer1-layer3只微调layer4和fc层 for name, param in model.named_parameters(): if layer4 not in name and fc not in name: param.requires_grad False # 替换最后的全连接层输出3类故障 model.fc nn.Linear(model.fc.in_features, 3) # 微调学习率设得很低epoch 也少 optimizer torch.optim.Adam( filter(lambda p: p.requires_grad, model.parameters()), lr1e-4 # 预训练模型微调学习率必须小 ) # 只训20个epoch多了就过拟合 for epoch in range(20): ...你可能会问CWRU是轴承数据客户是航空叶片领域不一样啊迁移有用吗别急往下看。确实如果源域和目标域差异太大迁移效果会打折扣。但振动信号的底层特征频谱结构、谐波模式、冲击响应在不同旋转机械之间是有共性的。我们实测下来预训练 微调的方案比从头训练好了不止一个档次——F1从0.42提到了0.79。当然如果源域和目标域完全八竿子打不着比如从图像分类模型迁移到振动信号那就别折腾了老实找同领域的数据集。五、一个争议点小样本下深度学习到底行不行很多人会觉得样本少就应该用传统机器学习深度学习是大数据的专属。但说实话这个观点在2024年已经有点过时了。我们做过一个对比实验用同样的30条故障样本来自一个泵阀监测项目分别训练 - 随机森林调参到最优 - 1D-CNN3层卷积参数量控制在5万以内 - 原型网络Prototypical Network专门为小样本设计的结果挺有意思的 - 随机森林F1 0.71训练5秒 - 1D-CNNF1 0.68训练2分钟——更差而且不稳定 - 原型网络F1 0.83训练30秒说白了小样本下不是深度学习不行是你用的架构不对。原型网络、关系网络、MAML 这些元学习架构就是为看几个样本就能学会设计的。2024年我们在3个项目里用了原型网络效果都稳定优于随机森林。但反过来想原型网络也有坑——它对特征提取器的要求很高如果特征提得不好原型在嵌入空间里聚不到一起那就白搭。所以通常的做法是先用大量无标签数据训练一个自编码器做特征提取再用原型网络做分类。写在最后小样本建模没有银弹。SMOTE 简单但有效信号增强能锦上添花迁移学习能救命原型网络则是前沿武器。最后说两句实操建议先试试随机森林 Borderline-SMOTE这是性价比最高的方案很多时候够用了。数据增强的噪声参数要调别抄个代码就跑sigma 差0.01结果可能差很多。迁移学习一定要冻结底层全层微调在小样本下等于从头训练预训练的优势全浪费了。别迷信深度学习小样本下一个调好的随机森林经常比瞎搞的神经网络强。上个月和一个做半导体设备监测的朋友聊他们厂里有台价值800万的刻蚀机3年才出了2次故障。我说你们这数据量上什么深度学习啊先攒够50条故障样本再说吧。他深以为然。数据是预测性维护的命根子模型只是锦上添花。在数据不够的时候先把能用的技巧都用上同时想办法多攒数据——这才是正经路子。