
簡介面向刀具磨損狀態識別場景的機器學習項目資源包整合CNN、LSTM、GRU、SVM、隨機森林等多種模型用于解決滾刀走刀數據下的磨損階段分類問題。整個資源包共包含15個文件核心為8個Python腳本分別負責數據合并、特征生成、模型訓練與測試等環節4個CSV文件提供銑刀1、4、6的走刀數據集另有PNG示意圖與Markdown說明文檔方便快速理解代碼結構。壓縮后僅2.54MB輕量且目錄結構清晰數據劃分明確銑刀1共315個樣本用于訓練銑刀4、6各315個樣本作為測試集可直接基于源碼運行減少數據整理與預處理工作量。目前已吸引276人學習適合正在從事工業故障診斷、時間序列分類課題的開發者參考。借助這套源碼可深入掌握一維CNN對時間序列局部特征的捕捉能力同時對比LSTM、GRU在序列建模上的表現以及SVM、隨機森林等傳統模型的基準效果訓練與測試腳本已按上述劃分準備好便于快速復現實驗、替換不同模型并在此基礎上擴展自己的特征工程方案。1. 用Python做滾刀狀態識別最容易被忽視的不是模型而是數據用Python做盾構/TBM滾刀狀態識別大多數人一上來就選模型把CNN、LSTM、GRU、SVM、隨機森林挨個試一遍結果發現測試集指標不錯現場一用就失靈。問題通常不在模型而在數據傳感器信號怎么切、標簽怎么對齊、時頻圖怎么生成、不平衡樣本怎么處理這些環節決定識別系統能否穩定落地。這里按一套可復用的工程流程把滾刀狀態識別的數據準備、特征構造、模型參數、訓練排錯和部署閾值串起來適合正在做工業數據挖掘或設備健康管理的工程師參考也適合作為入門機器學習的完整實戰案例。2. 滾刀狀態識別的數據與特征工程從傳感器信號到CNN輸入模型只是流水線的后半段。滾刀狀態識別通常不直接拿原始電壓信號送給模型而是先完成切片、去噪、特征化和標簽對齊。這一章按實際項目最常見的順序展開把數據采集和特征構造中的關鍵坑位講清楚。2.1 數據采集與狀態標簽對齊滾刀狀態識別用的數據工業現場最常見的是振動加速度信號傳感器安裝在刀盤或滾刀座附近同步采集的還有推進速度、轉速、推力、扭矩等工藝參數。采樣頻率要覆蓋可能出現的故障頻率一般不低于1kHz實驗臺條件下甚至會到10kHz以上。如果只用推力、扭矩這類工藝參數模型學到的更接近掘進工況而不是滾刀磨損所以振動信號才是識別磨損的核心來源。標簽是監督學習的起點。常見做法有兩種一種是在實驗臺上對滾刀做定時磨損測量用磨損量連續值劃分狀態另一種是在盾構機停機開倉時人工檢查滾刀磨損等級。第二種更貼近“狀態識別”的定義但檢查周期長標簽量少。無論哪種都要注意標簽對齊傳感器數據是連續流而標簽對應一個時間段如果直接把整段時間的樣本都標成同一狀態會混入狀態切換前后的過渡數據。一般建議把標簽邊界前后各裁掉一部分或者單獨設置一個驗證集排除邊界樣本避免模型學到“換刀前后”的時序假象。2.2 信號切片、濾波與歸一化的具體做法連續信號需要切成樣本。常見窗口長度為1到2秒重疊率50%。這樣每個樣本保留至少一個旋轉周期的完整信息又不會因為窗口太短丟失低頻分量。切完之后做三類處理去趨勢、帶通濾波、歸一化。去趨勢用于消除傳感器零漂帶通濾波抑制低頻擾動和高頻噪聲歸一化讓不同掘進環境的信號尺度可比。import numpy as np from scipy import signal def preprocess_signal(raw, fs1000, lowcut10, highcut500): # 去趨勢去除線性漂移 detrended signal.detrend(raw, typelinear) # 巴特沃斯帶通濾波order4 b, a signal.butter(4, [lowcut, highcut], btypebandpass, fsfs) filtered signal.filtfilt(b, a, detrended) # z-score歸一化消除振幅尺度差異 normalized (filtered - np.mean(filtered)) / np.std(filtered) return normalized def make_spectrogram(signal_1d, fs1000, nperseg128): # 短時傅里葉變換返回頻率軸、時間軸和功率譜 f, t, Sxx signal.spectrogram( signal_1d, fsfs, npersegnperseg, noverlapnperseg // 2 ) # 對數壓縮避免少量大值主導網絡梯度 return f, t, 10 * np.log10(Sxx 1e-10)參數說明detrend(typelinear)去掉線性趨勢項防止后續歸一化被緩慢漂移帶偏butter的4階帶通在1kHz采樣率下常用10~500Hz低頻段排除刀盤回轉分量高頻段濾掉電器噪聲filtfilt是零相位濾波避免群延遲導致標簽和信號錯位。nperseg決定頻率分辨率值越大頻率越細但時間分辨率越低128在1kHz下約對應0.128秒窗口適合滾刀沖擊類信號。2.3 時域、頻域和時頻圖像特征給CNN和SVM喂不同輸入CNN天然適合從時頻圖像里提取局部模式所以把一維信號轉成STFT灰度圖或小波時頻圖比直接輸入一維波形更穩定。傳統模型則需要一組手工特征喂給SVM和隨機森林。特征類型典型特征適用模型時域RMS、峰值因子、峭度、波形因子SVM、隨機森林、LSTM頻域重心頻率、均方頻率、頻帶能量占比SVM、隨機森林時頻圖像STFT灰度圖、CWT尺度圖CNN原始序列多時間步振動幅度LSTM、GRU常見誤區是讓LSTM去吃STFT圖或者讓CNN去吃一維波形。CNN看到的是“整張圖的空間結構”LSTM看到的是“時間步之間的順序依賴”。如果做混合模型需要保證數據量足夠否則容易過擬合。工程上更穩的做法是分別建基線再決定是否融合。生成CNN輸入時只需把預處理后的信號切片交給make_spectrogram保存為灰度圖即可。2.4 類別不平衡與數據增強別讓正常樣本淹沒磨損信號正常滾刀的樣本遠多于磨損和崩裂樣本直接訓練會讓分類器把所有樣本都判為“正常”。處理方式分兩類對深度學習模型在時頻圖上做增強對傳統模型在特征空間做重采樣。時頻圖增強可以用時間掩碼、頻率掩碼和隨機裁剪類似語音識別的SpecAugment思路但裁剪幅度不要太大否則高頻沖擊部分被丟光。from imblearn.over_sampling import SMOTE from sklearn.model_selection import train_test_split # X_features 是手工特征y_labels 是狀態類別 X_train, X_test, y_train, y_test train_test_split( X_features, y_labels, test_size0.2, stratifyy_labels, random_state42 ) # 只在訓練集上做SMOTE避免驗證集信息泄漏 smote SMOTE(k_neighbors3, random_state42) X_train_res, y_train_res smote.fit_resample(X_train, y_train)參數說明stratifyy_labels保證切分后各類別比例一致k_neighbors3是SMOTE合成樣本時的近鄰數設置過小容易生成噪聲點過大則合成樣本貼近原始點、失去多樣性。注意SMOTE只適合手工特征空間不能用于一維序列或時頻圖否則會破壞時間連續性。3. 模型選型與核心參數CNN、LSTM、GRU、SVM、隨機森林怎么調才能對比不同模型的輸入和參數差異很大但對比時必須使用同一份驗證集和同一組評估指標否則得到的“誰更好”不成立。這一章講清楚每個模型在滾刀狀態識別里的定位以及動手前必須確定的參數。3.1 CNN處理時頻圖的關鍵參數CNN輸入形狀是(height, width, 1)height對應頻率軸width對應時間軸。我一般先用兩個卷積塊看收斂情況而不是一上來堆ResNet。卷積核用3×3池化用2×2最大值池化濾波器數量按32、64、128遞增。優化器選Adam初始學習率1e-3配合學習率衰減。參數建議值說明batch_size16~64時頻圖占顯存較多太大容易OOMfilters32 - 64 - 128逐層翻倍kernel_size3×3對振動時頻圖的局部頻率-時間模式最穩dropout0.3~0.5放在全連接層之前optimizerAdam(lr1e-3)后期用ReduceLROnPlateau降到1e-5這里的關鍵是池化次數。輸入圖如果只有32×32池化兩次就變成8×8再池化會丟失太多細節。CNN在滾刀識別里容易過擬合因為樣本量通常只有幾千到幾萬所以Dropout和早停比網絡深度更重要。3.2 LSTM/GRU序列建模時間步長與門控單元選擇如果使用原始一維信號LSTM輸入形狀是(batch, time_steps, features)。time_steps決定模型能看到多長的歷史一般取采樣頻率的一半到一倍。例如1kHz采樣1秒窗口對應1000個時間步但直接塞給LSTM會讓訓練很慢。工程上會先降采樣到200~500Hz或者在一個時間步內放若干個采樣點的統計量。參數LSTMGRUunits32~12832~128dropout0.2~0.40.2~0.4bidirectional可選可選return_sequences最后一層False同左GRU參數少一個門在中小數據集上比LSTM更穩。滾刀狀態識別如果只有幾萬樣本優先試驗GRU。歸一化要按整個窗口的均值和標準差做不能在時間步內部單獨做否則破壞幅值變化信息。3.3 SVM和隨機森林特征尺度與類別權重SVM對特征尺度極其敏感必須先用StandardScaler。RBF核是最常用選擇C是誤分類懲罰gamma控制單個樣本的影響半徑。隨機森林不要求標準化但需要對特征做重要性篩選否則樹的分裂會被無關特征干擾。兩個模型都建議設置class_weightbalanced讓模型自動提高少數類權重。模型關鍵參數排查方向SVMkernelrbf, C10, gammascaleC過大過擬合gamma過小欠擬合隨機森林n_estimators500, min_samples_leaf2葉子節點太小容易過擬合通用class_weightbalanced解決類別不平衡實際項目中SVM在小樣本特征集上往往比深度學習高因為手工特征已經壓縮了信息。隨機森林訓練快還能輸出特征重要性適合作為篩選特征的工具。3.4 統一評估流程多模型對比不能只看準確率不平衡數據下準確率沒有意義要用macro F1和混淆矩陣。深度學習模型固定訓練/驗證/測試集切分傳統模型用5折交叉驗證。最后統一輸出分類報告。from sklearn.metrics import classification_report, confusion_matrix from tensorflow.keras.callbacks import EarlyStopping model.compile( losssparse_categorical_crossentropy, optimizeradam, metrics[accuracy] ) early EarlyStopping( monitorval_loss, patience10, restore_best_weightsTrue ) history model.fit( X_train, y_train, validation_data(X_val, y_val), epochs50, batch_size32, callbacks[early] ) y_pred np.argmax(model.predict(X_test), axis1) print(classification_report(y_test, y_pred)) print(confusion_matrix(y_test, y_pred))參數說明EarlyStopping監控驗證集loss連續10輪不改善就停止訓練restore_best_weightsTrue保證結束后的權重不是最后一輪而是驗證集最優的一輪。classification_report會輸出每個類別的precision、recall、F1比只看accuracy可靠得多。4. 從源碼到訓練滾刀狀態識別項目結構與實操代碼項目源碼通常會包含數據預處理、特征提取、模型訓練三個模塊。這一章給出一套能直接運行的代碼骨架并結合上一章的參數說明把散落的操作連起來。4.1 項目目錄與環境依賴怎么搭我習慣把數據、特征、模型、輸出分開配合統一的配置文件。目錄結構如下rolling_cutter_status/ ├── data/ │ ├── raw/ # 原始傳感器數據 │ ├── processed/ # 切片、去噪、增強后的數據 │ └── labels.csv # 狀態標簽 ├── features/ │ ├── extract_features.py │ └── make_spectrograms.py ├── models/ │ ├── train_cnn.py │ ├── train_lstm_gr.py │ ├── train_svm_rf.py │ └── evaluate.py ├── configs/ │ └── params.yaml └── outputs/ ├── checkpoints/ └── reports/依賴環境建議用conda或venv隔離。常用包與用途依賴包用途numpy/scipy信號處理與數值計算pandas標簽與特征表管理scikit-learnSVM、隨機森林、評估指標imbalanced-learnSMOTE過采樣tensorflowCNN、LSTM、GRU訓練matplotlib時頻圖繪制與結果可視化安裝時注意TensorFlow和Python版本兼容Windows上建議用WSL2或CPU版本跑小數據量實驗GPU版本再放到服務器。4.2 傳統機器學習模型訓練代碼SVM、隨機森林手工特征表通常已經降到幾十維先讀入特征和標簽再切訓練測試集。SVM需要pipeline隨機森林可以直接用原始特征。import pandas as pd from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier from sklearn.preprocessing import StandardScaler from sklearn.pipeline import make_pipeline train_df pd.read_csv(features/train_features.csv) X train_df.drop(label, axis1).values y train_df[label].values # SVM尺度敏感pipeline里做標準化 svm_model make_pipeline( StandardScaler(), SVC(kernelrbf, C10, gammascale, class_weightbalanced) ) svm_model.fit(X, y) # 隨機森林不要求標準化class_weight處理不平衡 rf_model RandomForestClassifier( n_estimators500, min_samples_leaf2, class_weightbalanced, n_jobs-1 ) rf_model.fit(X, y)參數說明class_weightbalanced讓模型在損失函數中提高少數類權重n_jobs-1使用所有CPU核并行訓練但保存的模型文件會更大。SVM的gammascale表示按特征數自動縮放避免手動調參。4.3 深度學習模型訓練代碼CNN、LSTM/GRUCNN讀入時頻譜圖輸入最后一維是通道數。這里以Keras為例先構建模型再結合上一章的早停策略訓練。import numpy as np from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout # spectrograms shape: (N, height, width) X np.load(data/processed/spectrograms.npy) y np.load(data/processed/labels.npy) X X[..., np.newaxis] # 增加通道維度 num_classes len(np.unique(y)) model Sequential([ Conv2D(32, (3, 3), activationrelu, paddingsame, input_shapeX.shape[1:]), MaxPooling2D((2, 2)), Conv2D(64, (3, 3), activationrelu, paddingsame), MaxPooling2D((2, 2)), Flatten(), Dense(128, activationrelu), Dropout(0.4), Dense(num_classes, activationsoftmax) ]) model.summary()說明X[..., np.newaxis]把(N, height, width)變成(N, height, width, 1)否則Conv2D會報錯。paddingsame讓卷積不縮小特征圖尺寸池化負責降維。全連接層輸出128維加Dropout是為了抑制過擬合最后的Dense輸出類別數softmax概率和為1。訓練LSTM/GRU時只需把輸入換成(batch, time_steps, features)模型第一層換成LSTM或GRU其余評估流程一致。4.4 訓練排錯過擬合、數據泄漏和標簽偏移實際訓練中遇到的絕大多數問題可以從損失曲線和混淆矩陣里看出來。以下是我的排查表現象可能原因對策訓練loss下降驗證loss上升過擬合增強數據、增加dropout、減少epoch準確率高但少數類召回低類別不平衡調整class_weight、用macro F1早停驗證指標高于測試指標很多數據泄漏檢查歸一化和SMOTE是否只fit在訓練集模型表現和標簽隨機打亂后差不多標簽時間對齊錯誤重新檢查標簽邊界裁掉過渡段數據泄漏最隱蔽。如果先對全量數據做StandardScaler再切分測試集的信息已經參與計算均值和方差測試結果會虛高。正確做法是只在訓練集上計算統計量再應用到驗證和測試集。標簽偏移可以通過時間偏移實驗驗證把標簽整體平移若干秒后重新訓練如果模型精度變化不大說明模型更多在學工況變化而不是滾刀狀態。5. 部署時的概率閾值調整滾刀狀態識別落地的最后一個技巧模型訓練完直接把argmax結果接到現場報警系統會很難受因為信號有波動單個樣本的預測類別會來回跳導致頻繁誤報。更穩的做法是輸出每個類別的概率然后在業務層設置“置信度閾值”和“猶豫區”。例如只有最大概率超過0.7才更新當前狀態概率在0.4到0.7之間保留上一次確認狀態這樣現場顯示是平滑的不會被單次抖動帶偏。import numpy as np def commit_status(proba, last_status, high_thres0.7, low_thres0.4): confidence np.max(proba) predicted int(np.argmax(proba)) if confidence high_thres: return predicted elif confidence low_thres: return last_status else: # 猶豫區維持上一個穩定狀態 return last_status代碼中的閾值需要根據現場誤報率調整。如果報警頻繁調高high_thres如果希望更早發現磨損調低閾值。這個閾值還可以按滾刀服役時間做動態調整比如更換新刀后前50米提高閾值越接近預估壽命越敏感。另一個落地細節是模型導出和預處理參數固化。訓練好的Keras模型可以先保存為H5或SavedModel再轉成ONNX或TFLite格式脫離Python環境部署到C或Java服務里。轉換前要確認預處理邏輯一致特別是濾波系數和歸一化統計量必須和訓練時完全相同否則概率分布會漂移現場效果大打折扣。model.save(models/cnn.h5) # 轉換成輕量化TFLite方便邊緣設備加載 converter tf.lite.TFLiteConverter.from_keras_model(model) tflite_model converter.convert() with open(models/cnn.tflite, wb) as f: f.write(tflite_model)部署時建議把lowcut、highcut、nperseg、歸一化均值方差寫進配置文件與模型文件一起發布。這樣一旦現場出現異常可以先檢查配置是否被改過而不是懷疑模型本身。滾刀狀態識別最考驗工程一致性數據和模型在訓練時是什么樣子部署時就應該原樣重現真正的精度不是訓練出來的是每一步都不走樣地保下來的。本文還有配套的精品資源點擊獲取