AI時代的網站與手機App建置與開發Part25 - ML.NET與聲音異常偵測
· 摘要
將異常偵測應用在聲音資料能夠預警機器運作的失誤, 例如預警馬逹, 幫浦, 閥門開關, 齒輪, 滑軌, 或是風扇的運作是否異常, 或是預警汽機車, 輪船, 甚至飛機的引擎狀態等等, 對於24小時不間斷的生產線能夠提供重要的營運支援.
圖: 機械運作聲音異常預警示意圖
在本篇文章中, 我們將使用Microsoft ML.NET搭配Librosa聲音處理程式庫執行聲音的異常偵測, 期能利用AI模型支援24小時不間斷的營運作業.
· 準備訓練資料
首先請啟動瀏覽器, 瀏覽至MIMII DUE: Sound Dataset for Malfunctioning Industrial Machine
Investigation and Inspection with Domain Shifts due to Changes in Operational
and Environmental Conditions, 下載訓練聲音資料集(下載網址: https://zenodo.org/records/4740355).
本篇文章將會從上述的下載網址下載幫浦(Pump)運作的聲音檔案, 然後將其中的10個正常的幫浦運作聲音檔案加入到名稱為NormalSounds的資料夾中, 再將其中的10個異常的幫浦運作聲音檔案加入到名稱為AbnormalSounds的資料夾中(讀者可以視需要加入更多的聲音檔案, 以提升訓練的機器學習模型的準確度), 做好之後, 請到[屬性]視窗將所有的聲音檔案的[複製到輸出目錄]屬性的內容值設定為:有更新時才複製.
· 實作取得聲音檔案特徵向量的Python程式
import librosa
import pandas as pd
import numpy as np
import os
# 讀取資料夾中的聲音檔案, 並將檔案的檔案名稱建立成字串陣列後傳回
def get_filenames_in_folder(folder_path):
filenames = []
for filename in os.listdir(folder_path): # 取得資料夾中的所有內容
if os.path.isfile(os.path.join( folder_path, filename)): # 如果是檔案
filenames.append(filename) # 將檔案名稱加入到陣列
return filenames
# 使用MFCC(Mel Frequency Cepstral
Coefficients)演算法取得聲音的特徵向量
def extract_features(foldername,
file_path):
audio, sample_rate =
librosa.load(
f"{foldername}/{file_path}", sr=None) # 讀取聲音檔案
mfccs = librosa.feature.mfcc(y=audio,
sr=sample_rate,
n_mfcc=13) # 取得聲音的特徵
mfccs_mean =
np.mean(mfccs, axis=1) # 計算平均值
return mfccs_mean # 傳回平均值
# 取得NormalSounds資料夾中正常的聲音檔案, 將檔案名稱建立成字串陣列
folder_path = 'NormalSounds'
normal_audio_files =
get_filenames_in_folder(folder_path)
print(normal_audio_files)
# 取得正常聲音檔案的特徵向量
features =
[extract_features(folder_path, f) for f in normal_audio_files]
dfNormal = pd.DataFrame(features)
# 將特徵向量建立成DataFrame
# 為DataFrame加入名稱為Label的欄位, 並將欄位內容值設定為0(正常)
dfNormal['Label'] = 0
# 取得AbnormalSounds資料夾中異常的聲音檔案, 將檔案名稱建立成字串陣列
folder_path = 'AbnormalSounds'
abnormal_audio_files =
get_filenames_in_folder(folder_path)
print(abnormal_audio_files)
# 取得異常聲音檔案的特徵向量
features =
[extract_features(folder_path, f)
for f
in abnormal_audio_files]
dfAbnormal = pd.DataFrame(features)
# 將特徵向量建立成DataFrame
# 為DataFrame加入名稱為Label的欄位, 並將欄位內容值設定為1(異常)
dfAbnormal['Label'] = 1
df = pd.concat([dfNormal,
dfAbnormal],
ignore_index=True) # 串連dfNormal, dfAbnormal兩個DataFrame
df.to_csv("audio_features.csv",
index=False) # 將DataFrame的內容寫成純文字文件供訓練使用
執行上述的Python程式, 會擷取當做訓練資料的聲音檔案的特徵向量, 並儲存成名稱為audio_features.csv的文件, 供ML.NET訓練時使用.
圖1所示即為名稱為audio_features.csv的文件的部分內容:
圖1: 名稱為audio_features.csv的文件的部分內容
請名稱為audio_features.csv的文件加入到Visual Studio專案中, 並到[屬性]視窗將[複製到輸出目錄]屬性的內容值設定為:有更新時才複製.
· 使用ML.NET偵測聲音內容異常
首先我們要定義描述訓練圖片資料的ImageData類別和描述圖片特徵向量的ImageFeatures類別.
· 定義聲音特徵向量的AudioFeature類別
// 描述聲音特徵向量的類別
public class AudioFeature
{
[LoadColumn(0, 12)] // 載入0~12, 共13個欄位的特徵向量的內容值
[VectorType(13)]
public float[] Features { get; set; }
[LoadColumn(13)]
// 載入Label檔案的內容值
public float Label { get; set; }
}
· 定義描述圖片特徵向量的ImageFeatures類別
// 描述預測結果的類別
public class AnomalyPrediction
{
[ColumnName("PredictedLabel")]
public bool Prediction { get; set; }
}
· 實作聲音異常偵測
private void btnDetect_Click(object sender, EventArgs e)
{
var mlContext = new MLContext(); // 建立MLContext類別的物件
var dataPath = "audio_features.csv"; // 存放聲音特徵向量的檔案名稱
IDataView data =
mlContext.Data.LoadFromTextFile<AudioFeature>(
path:
dataPath, hasHeader: true,
separatorChar: ','); // 載入存放聲音特徵向量的檔案的內容
// 指定特徵向量的內容為訓練資料(即Features)
var pipeline =
mlContext.Transforms.Concatenate("Features",
nameof(AudioFeature.Features))
.Append(mlContext.Transforms.NormalizeMinMax(
"Features")) // 將特徵向量的內容值轉換成0~1之間的數字
.Append(mlContext.AnomalyDetection.Trainers.RandomizedPca(
featureColumnName: "Features",
rank: 2)); // 使用RandomizedPca演算法進行訓練
var model = pipeline.Fit(data);
// 執行訓練
var transformedData =
model.Transform(data); // 取得訓練結果
var metrics =
mlContext.AnomalyDetection.Evaluate(
transformedData, labelColumnName: "Label"); // 評估訓練結果
// 顯示Area
Under the ROC Curve (AUC-ROC)值
Trace.WriteLine($"Area Under ROC: {metrics.AreaUnderRocCurve}");
// 顯示Detection Rate At False Positive Count值
Trace.WriteLine($@"Detection Rate at False Positive Count:
{metrics.DetectionRateAtFalsePositiveCount}");
var predictionEngine =
mlContext.Model.CreatePredictionEngine
<AudioFeature, AnomalyPrediction>(model);
// 建立預測引擎
// 使用訓練資料的最後一筆當做測試資料
var newSample = new AudioFeature
{
Features = mlContext.Data.CreateEnumerable<AudioFeature>(
data, reuseRowObject: false).Last().Features
};
var prediction =
predictionEngine.Predict(newSample); // 執行預測
Trace.WriteLine(
$"Is Anomaly? {prediction.Prediction}"); // 顯示預測結果
}
執行上述的程式碼會顯示判定聲音檔案是否異常預測結果, 如圖2所示:
圖2: 判定測試的聲音檔案是否異常的結果
· 預測結果說明
1. Area Under ROC值:
ROC是Receiver Operating Characteristic的縮寫, 代表二元分類演算法(binary classification)的品質.
ROC曲線是以TPR(正常資料被正確檢出的比例)為Y軸, 以FPR(異常資料未被正確檢出的比例)為X軸畫出來的曲線, 而Area Under ROC(AUC)值判讀如下:
- 如果AUC =
1: 完美的模型, 能夠正確檢測出正常和異常的資料
- 如果AUC =
0.5: 沒有比亂猜更好的模型, 即沒有檢測能力的模型
- 如果AUC
< 0.5: 比亂猜更差的模型
2. Detection Rate at a Specific False Positive
Count
Detection Rate at False Positive Count也是一個用來評估二元分類演算法品質的常用指標. 常異常資料未被正確檢測出代價高昂, 或是不能容許時, 會檢視異常資料未被正確檢測出的數量或比例固定在某個值(容許底限)時, 正常資料被正確檢出的比例
範例下載:


留言
張貼留言