在本文中,我們將展示如何使用 TinyML 和 Edge Impulse 為 Arduino Nano BLE Sense 構(gòu)建咳嗽檢測系統(tǒng)。
這篇文章主要講述如何使用Edge Impulse在 Arduino Nano BLE Sense 上進(jìn)行機(jī)器學(xué)習(xí),以檢測實(shí)時音頻中是否存在咳嗽。我們構(gòu)建了咳嗽和背景噪聲樣本的數(shù)據(jù)集,并應(yīng)用了高度優(yōu)化的 TInyML 模型,構(gòu)建了一個咳嗽檢測系統(tǒng),該系統(tǒng)在 Nano BLE Sense 上 20 kB 的 RAM 中實(shí)時運(yùn)行。同樣的方法適用于許多其他嵌入式音頻模式匹配應(yīng)用,例如老年人護(hù)理、安全和機(jī)器監(jiān)控。該項目和數(shù)據(jù)集最初由 Kartik Thakore 啟動,以幫助 COVID-19 工作。
前提
要想完成該項目,首先有以下要求:
對軟件開發(fā)和Arduino的基本了解
安裝 Arduino IDE 或 CLI
帶麥克風(fēng)的Arduino Nano BLE Sense或等效 Cortex-M4+ 板(可選)
我們將使用 Edge Impulse,一個在邊緣設(shè)備上進(jìn)行機(jī)器學(xué)習(xí)的在線開發(fā)平臺。你需要先注冊創(chuàng)建一個免費(fèi)帳戶。登錄您的帳戶,并通過單擊標(biāo)題為您的新項目命名。我們稱之為“Arduino Cough Tutorial”。
收集數(shù)據(jù)集
任何機(jī)器學(xué)習(xí)項目的第一步都是收集一個數(shù)據(jù)集,該數(shù)據(jù)集代表我們希望能夠在我們的 Arduino 設(shè)備上匹配的已知數(shù)據(jù)樣本。首先,我們創(chuàng)建了一個包含 10 分鐘音頻的小型數(shù)據(jù)集,分為“咳嗽”和“噪音”兩個類別。我們將展示如何將此數(shù)據(jù)集導(dǎo)入您的 Edge Impulse 項目,添加您自己的樣本,甚至從頭開始您自己的數(shù)據(jù)集。該數(shù)據(jù)集很小,并且具有有限數(shù)量的咳嗽和軟背景噪聲樣本。因此,該數(shù)據(jù)集僅適用于實(shí)驗,本教程中生成的模型只能區(qū)分安靜的背景噪音和小范圍的咳嗽。我們鼓勵您使用更廣泛的咳嗽、背景噪音和其他類別(如人類語音)來擴(kuò)展數(shù)據(jù)集,以提高性能。
注意:強(qiáng)迫自己咳嗽對聲帶的傷害很大,收集數(shù)據(jù)和測試時要小心!
首先下載我們的咳嗽數(shù)據(jù)集并在您的 PC 上您選擇的位置提取文件:https ://cdn.edgeimpulse.com/datasets/cough.zip
您可以使用Edge Impulse CLI Uploader將此數(shù)據(jù)集導(dǎo)入您的 Edge Impulse 項目。按照這些安裝說明安裝 Edge Impulse CLI。
打開終端或命令提示符,然后導(dǎo)航到您提取文件的文件夾。
運(yùn)行:
$ edge-impulse-uploader --clean
$ edge-impulse-uploader --category training training/*
$ edge-impulse-uploader --category testing testing/*
系統(tǒng)將提示您輸入 Edge Impulse 用戶名、密碼和要添加數(shù)據(jù)集的項目。數(shù)據(jù)集樣本現(xiàn)在將在數(shù)據(jù)采集頁面上可見。通過單擊示例,我們可以看到示例的外觀,并通過單擊每個圖表下方的播放按鈕來收聽音頻。
10 分鐘的咳嗽和噪音數(shù)據(jù)樣本足以開始。您可以選擇使用自己的咳嗽和背景噪聲樣本擴(kuò)展數(shù)據(jù)集。我們可以從數(shù)據(jù)采集頁面直接從設(shè)備收集新的數(shù)據(jù)樣本。WAV 格式的音頻樣本也可以使用Edge Impulse CLI Uploader 上傳。
重要提示:現(xiàn)實(shí)世界應(yīng)用程序中使用的模型應(yīng)使用盡可能多樣化的數(shù)據(jù)集進(jìn)行訓(xùn)練和測試。這個初始數(shù)據(jù)集相對較小,因此當(dāng)暴露于不同類型的背景噪音或來自不同人的咳嗽時,模型的表現(xiàn)會不一致。
最簡單的入門方法是使用手機(jī)收集音頻數(shù)據(jù)。轉(zhuǎn)到“設(shè)備”頁面,然后單擊右上角的“+ 連接新設(shè)備”按鈕。選擇“使用您的手機(jī)”。這將生成一個唯一的 QR 碼,以在您的手機(jī)瀏覽器上打開一個 Web 應(yīng)用程序。對二維碼拍照,然后選擇打開鏈接。
Web 應(yīng)用程序?qū)⑦B接到您的 Edge Impulse 項目,應(yīng)該如下所示:
我們現(xiàn)在可以從Edge Impulse的數(shù)據(jù)采集頁面直接從手機(jī)中收集音頻數(shù)據(jù)樣本。在“記錄新數(shù)據(jù)”部分,輸入“咳嗽”或“噪音”標(biāo)簽,確保選擇“麥克風(fēng)”作為傳感器,然后單擊“開始采樣”。您的手機(jī)現(xiàn)在將收集音頻樣本,并將其添加到您的數(shù)據(jù)集中。
還支持直接從 Nano BLE Sense 板收集音頻數(shù)據(jù)。按照這些說明安裝 Edge Impulse 固件和守護(hù)程序。一旦設(shè)備連接到 Edge Impulse,您就可以像上面的手機(jī)一樣收集數(shù)據(jù)樣本。
創(chuàng)造你的脈沖
接下來,我們將在創(chuàng)建脈沖頁面上選擇信號處理和機(jī)器學(xué)習(xí)模塊。脈沖將從空白開始,帶有原始數(shù)據(jù)和輸出特征塊。保留 1000 ms 窗口大小和 500 ms 窗口增加的默認(rèn)設(shè)置。這意味著我們的音頻數(shù)據(jù)將一次處理 1 秒,每 0.5 秒開始。使用小窗口可以節(jié)省嵌入式設(shè)備上的內(nèi)存,但這意味著我們需要在兩次咳嗽之間沒有大間隔的咳嗽數(shù)據(jù)樣本。
單擊“添加處理塊”并選擇音頻 (MFCC)塊。接下來單擊“添加學(xué)習(xí)塊”并選擇神經(jīng)網(wǎng)絡(luò) (Keras)塊。點(diǎn)擊“保存沖動”。音頻塊將為每個音頻窗口提取頻譜圖,神經(jīng)網(wǎng)絡(luò)塊將被訓(xùn)練以根據(jù)我們的訓(xùn)練數(shù)據(jù)集將頻譜圖分類為“咳嗽”或“噪音”。您產(chǎn)生的脈沖將如下所示:
接下來,我們將從MFCC頁面上的訓(xùn)練數(shù)據(jù)集生成特征。此頁面顯示從任何數(shù)據(jù)集樣本中提取的每 1 秒窗口的頻譜圖的樣子。我們可以將參數(shù)保留為默認(rèn)值。
接下來單擊“生成特征”按鈕,然后使用此處理塊處理整個訓(xùn)練數(shù)據(jù)集。這將創(chuàng)建完整的特征集,用于在下一步訓(xùn)練我們的神經(jīng)網(wǎng)絡(luò)。按“生成特征”按鈕開始處理,這需要幾分鐘才能完成。
我們現(xiàn)在可以在 NN 分類器頁面上繼續(xù)設(shè)置和訓(xùn)練我們的神經(jīng)網(wǎng)絡(luò)。默認(rèn)神經(jīng)網(wǎng)絡(luò)適用于流水等連續(xù)聲音??人詸z測更復(fù)雜,因此我們將在每個窗口的頻譜圖上使用 2D 卷積配置更豐富的網(wǎng)絡(luò)。2D 卷積以與圖像分類類似的方式處理音頻頻譜圖。按“神經(jīng)網(wǎng)絡(luò)設(shè)置”部分的右上角,然后選擇“切換到 Keras(專家)模式”。
將“神經(jīng)網(wǎng)絡(luò)架構(gòu)”定義替換為以下代碼,并將“最小置信度”設(shè)置為“0.70”。然后繼續(xù)單擊“開始培訓(xùn)”按鈕。訓(xùn)練將需要幾秒鐘。
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, InputLayer, Dropout, Flatten, Reshape, BatchNormalization, Conv2D, MaxPooling2D, AveragePooling2D
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.constraints import MaxNorm
# model architecture
model = Sequential()
model.add(InputLayer(input_shape=(X_train.shape[1], ), name='x_input'))
model.add(Reshape((int(X_train.shape[1] / 13), 13, 1), input_shape=(X_train.shape[1], )))
model.add(Conv2D(10, kernel_size=5, activation='relu', padding='same', kernel_constraint=MaxNorm(3)))
model.add(AveragePooling2D(pool_size=2, padding='same'))
model.add(Conv2D(5, kernel_size=5, activation='relu', padding='same', kernel_constraint=MaxNorm(3)))
model.add(AveragePooling2D(pool_size=2, padding='same'))
model.add(Flatten())
model.add(Dense(classes, activation='softmax', name='y_pred', kernel_constraint=MaxNorm(3)))
# this controls the learning rate
opt = Adam(lr=0.005, beta_1=0.9, beta_2=0.999)
# train the neural network
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
model.fit(X_train, Y_train, batch_size=32, epochs=9, validation_data=(X_test, Y_test), verbose=2)
該頁面將顯示訓(xùn)練性能和設(shè)備上的性能,根據(jù)您的數(shù)據(jù)集應(yīng)如下所示:
我們的咳嗽檢測算法現(xiàn)在可以試用了!
測試
實(shí)時分類頁面允許我們使用數(shù)據(jù)集附帶的現(xiàn)有測試數(shù)據(jù)或通過手機(jī)或 Arduino 設(shè)備中的流式音頻數(shù)據(jù)來測試算法。我們可以從一個簡單的測試開始,選擇任何測試樣本,然后按“加載樣本”。這將對測試樣本進(jìn)行分類并顯示結(jié)果:
我們還可以使用實(shí)時數(shù)據(jù)測試算法。通過刷新我們之前打開的手機(jī)上的瀏覽器頁面,從您的手機(jī)開始。然后在“分類新數(shù)據(jù)”部分中選擇您的設(shè)備,然后按“開始采樣”。當(dāng)通過 edge-impulse-daemon 連接到項目時,您可以類似地從 Nano BLE Sense 流式傳輸音頻樣本,就像在數(shù)據(jù)收集步驟中一樣。
部署
我們可以輕松地將我們的咳嗽檢測算法部署到手機(jī)上。轉(zhuǎn)到手機(jī)上的瀏覽器窗口并刷新,然后按“切換到分類模式”按鈕。這將自動將項目構(gòu)建到 WebAssembly 包中并在您的手機(jī)上連續(xù)執(zhí)行(之后無需云,甚至進(jìn)入飛行模式?。?/p>
接下來,我們可以通過轉(zhuǎn)到部署頁面將算法部署到 Nano BLE Sense。在“構(gòu)建固件”下選擇“Arduino Nano 33 BLE Sense”,然后單擊“構(gòu)建”。
這將為 Nano BLE Sense 構(gòu)建一個完整的固件,包括您的最新算法。按照屏幕上的說明使用二進(jìn)制文件刷新您的 Arduino 板。
刷新 Arduino 后,我們可以在設(shè)備以 115、200 波特插入 USB 時打開設(shè)備的串行端口。串口打開后,按回車鍵得到提示,然后:
> AT+RUNIMPULSE
Inferencing settings:
? ? Interval: 0.06 ms.
? ? Frame size: 16000
? ? Sample length: 1000 ms.
? ? No. of classes: 2
Starting inferencing, press 'b' to break
Recording...
Recording done
Predictions (DSP: 495 ms., Classification: 84 ms., Anomaly: 0 ms.):?
? ? cough: 0.01562
? ? noise: 0.98438
Starting inferencing in 2 seconds...
Recording...
Recording done
Predictions (DSP: 495 ms., Classification: 84 ms., Anomaly: 0 ms.):
? ? cough: 0.01562
? ? noise: 0.98438
Starting inferencing in 2 seconds...
Recording...
Recording done
Predictions (DSP: 495 ms., Classification: 84 ms., Anomaly: 0 ms.):
? ? cough: 0.86719
? ? noise: 0.13281
Starting inferencing in 2 seconds...
Recording...
Recording done
Predictions (DSP: 495 ms., Classification: 84 ms., Anomaly: 0 ms.):
? ? cough: 0.01562
? ? noise: 0.98438
未來可能的拓展
使用您自己的咳嗽和背景聲音擴(kuò)展默認(rèn)數(shù)據(jù)集,記得定期重新訓(xùn)練和測試。您可以在測試頁面下設(shè)置單元測試,以確保模型在擴(kuò)展時仍然有效。
為不咳嗽的人類聲音添加一個新類和數(shù)據(jù),例如背景語音、打哈欠等。
從一個新數(shù)據(jù)集開始,收集音頻樣本以檢測新事物。
根據(jù)這些說明部署到 Arduino 庫,作為 Arduino Sketch 的一部分,以使用 LED 或顯示器顯示咳嗽檢測
評論