發(fā)快人一步)
做AIoT項(xiàng)目最頭疼的是什么不是模型選型不是云平臺(tái)對(duì)接而是最不起眼的傳感器數(shù)據(jù)采集和預(yù)處理。我在用ST的智能傳感器做運(yùn)動(dòng)識(shí)別項(xiàng)目時(shí)經(jīng)常在配置寄存器、調(diào)試中斷、清洗數(shù)據(jù)這些環(huán)節(jié)耗掉大半時(shí)間。直到我試用了ST官方推出的Web-Based Tool配合帶機(jī)器學(xué)習(xí)核的智能傳感器Smart Sensors整個(gè)AIoT項(xiàng)目的推進(jìn)速度才真正提起來(lái)。這篇就聊聊這個(gè)工具的實(shí)際體驗(yàn)、操作流程和踩過(guò)的坑適合正在做智能傳感器應(yīng)用或者準(zhǔn)備把AI算法往邊緣端遷移的朋友參考。1. 智能傳感器才是AIoT落地的關(guān)鍵為什么以前這么難用1.1 傳統(tǒng)方案的數(shù)據(jù)處理瓶頸在哪里大部分AIoT項(xiàng)目的鏈路都長(zhǎng)這樣傳感器采集原始數(shù)據(jù)MCU通過(guò)I2C或SPI把數(shù)據(jù)讀上來(lái)再跑到云端或者本地跑算法最后把結(jié)果反饋到應(yīng)用層。聽(tīng)著很順但實(shí)際跑起來(lái)問(wèn)題一堆。以六軸慣性傳感器為例光是一個(gè)加速度計(jì)的原始數(shù)據(jù)流在400Hz的采樣率下每秒鐘就有2400個(gè)浮點(diǎn)數(shù)要處理。如果主控是一顆Cortex-M0級(jí)別的低功耗MCU光是把這些數(shù)據(jù)從FIFO里搬出來(lái)再跑個(gè)濾波算法CPU占用率就能吃掉一半以上。真正的瓶頸不在“采集”而在“搬運(yùn)”和“判斷”。傳感器源源不斷產(chǎn)生數(shù)據(jù)MCU卻只有那么點(diǎn)算力和內(nèi)存。要是所有判斷邏輯都放在云端網(wǎng)絡(luò)延遲先不談功耗和隱私就是兩座大山?,F(xiàn)場(chǎng)的設(shè)備往往要求毫秒級(jí)響應(yīng)比如工業(yè)設(shè)備的異常振動(dòng)檢測(cè)、穿戴設(shè)備的跌倒識(shí)別這些東西怎么可能每次都等數(shù)據(jù)上傳到云端再返回結(jié)果而且很多場(chǎng)景的網(wǎng)絡(luò)環(huán)境壓根不穩(wěn)定斷網(wǎng)即罷工的方案沒(méi)人敢用。1.2 ST把機(jī)器學(xué)習(xí)搬進(jìn)傳感器的做法意法半導(dǎo)體針對(duì)這個(gè)痛點(diǎn)給出的方案很有意思與其讓MCU或云端累死累活地算不如讓傳感器自己在內(nèi)部把活干了。他們推出的LSM6DSOX、LSM6DSV16X這類(lèi)智能傳感器內(nèi)部直接集成了機(jī)器學(xué)習(xí)核MLC和可配置的有限狀態(tài)機(jī)FSM。MLC可以在傳感器內(nèi)部運(yùn)行決策樹(shù)模型直接把“是否跌倒”“是否靜止”“是否在走路”這類(lèi)判斷結(jié)果輸出到中斷引腳MCU只需要在中斷觸發(fā)時(shí)讀一個(gè)結(jié)果寄存器就行。這種“傳感器內(nèi)判斷”的架構(gòu)一下把數(shù)據(jù)鏈路的負(fù)擔(dān)降下來(lái)了。MCU不再需要處理原始數(shù)據(jù)流而是處理“語(yǔ)義”級(jí)別的結(jié)果。我用LSM6DSOX做過(guò)一個(gè)跌倒檢測(cè)的demo過(guò)去需要MCU側(cè)跑一個(gè)幾百行的姿態(tài)解算算法現(xiàn)在直接在傳感器內(nèi)部跑訓(xùn)練好的決策樹(shù)MCU代碼量壓縮了80%以上整機(jī)功耗也降了一個(gè)量級(jí)。這不只是少寫(xiě)幾行代碼的問(wèn)題是從系統(tǒng)架構(gòu)上改變了AIoT設(shè)備的能耗模型和實(shí)時(shí)性邊界。1.3 從零上手配置MLC的舊流程有多痛苦硬件能力擺在那里但以前想讓機(jī)器學(xué)習(xí)核跑起來(lái)過(guò)程真的很勸退。先得翻幾百頁(yè)的數(shù)據(jù)手冊(cè)搞清楚寄存器地址然后手動(dòng)配置十來(lái)個(gè)寄存器把MLC打開(kāi)再按照特定格式把決策樹(shù)參數(shù)填進(jìn)去。哪里填錯(cuò)了就得對(duì)著邏輯分析儀看波形一行一行地查。我當(dāng)年第一次調(diào)FSM的時(shí)候光是把一個(gè)簡(jiǎn)單的“抬手檢測(cè)”狀態(tài)機(jī)跑通就花了兩天。而且MLC的模型參數(shù)不是隨便填的需要先用Weka這類(lèi)工具離線(xiàn)訓(xùn)練決策樹(shù)然后手工把樹(shù)結(jié)構(gòu)轉(zhuǎn)換成ST定義的格式再按照寄存器地址表逐項(xiàng)映射。整個(gè)過(guò)程完全靠人工沒(méi)有任何可視化手段出錯(cuò)了也不知道是樹(shù)的結(jié)構(gòu)錯(cuò)了還是參數(shù)填錯(cuò)了。正是因?yàn)檫@段經(jīng)歷當(dāng)我發(fā)現(xiàn)ST推出了Web端工具時(shí)第一反應(yīng)是先看看這套流程是不是真的被簡(jiǎn)化掉了。2. ST Web工具的核心能力拆解2.1 工具定位把專(zhuān)家經(jīng)驗(yàn)封裝成網(wǎng)頁(yè)這個(gè)Web-Based Tool的定位很直接把傳感器選型、配置、模型訓(xùn)練、代碼生成這一整條鏈路搬進(jìn)瀏覽器。它不是一個(gè)簡(jiǎn)單的小工具而是ST整個(gè)智能傳感器開(kāi)發(fā)生態(tài)的中樞。用我的理解來(lái)說(shuō)它就是一顆“傳感器開(kāi)發(fā)向?qū)А卑岩郧胺稚⒃跀?shù)據(jù)手冊(cè)、應(yīng)用筆記、桌面軟件里的知識(shí)集中成一個(gè)交互式的網(wǎng)頁(yè)應(yīng)用。不需要安裝任何桌面環(huán)境打開(kāi)瀏覽器登錄就能用這對(duì)跨平臺(tái)團(tuán)隊(duì)協(xié)作特別友好。硬件工程師在Windows上配置傳感器參數(shù)算法工程師在Mac上訓(xùn)練模型數(shù)據(jù)標(biāo)注人員可能用的是Linux大家打開(kāi)同一個(gè)鏈接就能看到最新?tīng)顟B(tài)。從工具鏈的角度看這比傳統(tǒng)的桌面IDE方便太多。2.2 核心模塊從選型到代碼生成一整套整個(gè)工具按項(xiàng)目流程可以拆成幾塊傳感器選型匹配、應(yīng)用場(chǎng)景模板、數(shù)據(jù)采集與標(biāo)注、模型訓(xùn)練評(píng)估、配置生成與代碼導(dǎo)出。選型模塊會(huì)先根據(jù)你的應(yīng)用場(chǎng)景推薦合適的傳感器型號(hào)比如要做振動(dòng)監(jiān)測(cè)就推帶MLC的LSM6DSOX要做氣壓計(jì)輔助定位就推LSM6DSV16X配合氣壓傳感器。最有價(jià)值的是里面的場(chǎng)景模板庫(kù)。內(nèi)置了運(yùn)動(dòng)識(shí)別、異常檢測(cè)、姿態(tài)估計(jì)、環(huán)境監(jiān)測(cè)等常見(jiàn)場(chǎng)景的完整配置模板選一個(gè)模板進(jìn)去工具會(huì)自動(dòng)幫你把合適的ODR輸出數(shù)據(jù)速率、量程、濾波器配置、MLC決策樹(shù)結(jié)構(gòu)都填好。如果你和我一樣不是傳感器算法科班出身拿一個(gè)模板改成自己的需求比從白紙開(kāi)始不知道快多少倍。2.3 和ST傳感器全家桶之間的關(guān)系很多朋友可能在ST官網(wǎng)看到過(guò)SensorTile開(kāi)發(fā)套件、NanoEdge AI Studio等一堆工具容易搞混。簡(jiǎn)單理一下定位SensorTile是硬件開(kāi)發(fā)板NanoEdge AI Studio是幫你在MCU上跑AI模型的工具而這個(gè)Web工具則負(fù)責(zé)傳感器側(cè)的行為配置和模型生成。三者其實(shí)是同一生態(tài)的不同環(huán)節(jié)。對(duì)于做AIoT項(xiàng)目的朋友我建議的完整鏈路是用Web工具完成傳感器配置和MLC模型訓(xùn)練再把生成的配置代碼和模型參數(shù)燒進(jìn)SensorTile或者自己的硬件板卡最后如果需要更復(fù)雜的模型可以用NanoEdge AI Studio在MCU側(cè)做二次推理。三套工具搭配起來(lái)從傳感器到主控的AI推理鏈路就完整了。2.4 與云端AI平臺(tái)的協(xié)作方式這套工具也提供了數(shù)據(jù)導(dǎo)入導(dǎo)出的能力訓(xùn)練好的模型參數(shù)可以導(dǎo)出成C語(yǔ)言頭文件也可以直接生成完整的項(xiàng)目工程。我試過(guò)把工具導(dǎo)出的模型參數(shù)直接融合到自己的FreeRTOS工程里整個(gè)移植過(guò)程比想象中順利因?yàn)樯傻呐渲媒Y(jié)構(gòu)非常清晰每個(gè)寄存器的含義都有注釋。3. 實(shí)操全流程5分鐘跑通一個(gè)智能跌倒檢測(cè)3.1 明確目標(biāo)與硬件準(zhǔn)備這次實(shí)操的目標(biāo)是基于LSM6DSOX做一個(gè)“跌倒識(shí)別”的智能傳感器節(jié)點(diǎn)。硬件只需要一塊ST的STEVAL-MKI197V1子板或者像NUCLEO-F401RE這樣帶Arduino接口的開(kāi)發(fā)板再加一塊STEVAL-MKI109V3主板通過(guò)USB連接電腦。如果你手頭暫時(shí)沒(méi)有硬件板卡也沒(méi)關(guān)系工具本身支持模擬模式可以在網(wǎng)頁(yè)端直接采集模擬數(shù)據(jù)并生成配置。先明確幾個(gè)關(guān)鍵參數(shù)量程選±4gODR選208Hz這個(gè)組合是權(quán)衡了精度、信噪比和功耗之后比較常用的一組。如果你的應(yīng)用場(chǎng)景是低功耗穿戴設(shè)備可以適當(dāng)降低ODR到104Hz如果是工業(yè)振動(dòng)檢測(cè)可能要把量程改到±8g甚至±16g。參數(shù)不是越高越好夠用就行。3.2 使用Web工具完成傳感器配置在瀏覽器里打開(kāi)ST的Web工具新建項(xiàng)目后選擇傳感器型號(hào)LSM6DSOX。進(jìn)入配置界面后我會(huì)先用隨附的可視化工具觀(guān)察傳感器在靜止、走路、跌倒等不同狀態(tài)下的波形特征這樣對(duì)后面參數(shù)的選擇會(huì)比較有底。常見(jiàn)的做法是先用評(píng)估板連接目標(biāo)硬件然后在頁(yè)面上打開(kāi)實(shí)時(shí)數(shù)據(jù)流觀(guān)察加速度計(jì)三軸的波形。靜止時(shí)X軸大概是1g的重力分量走路時(shí)會(huì)有周期性的波動(dòng)跌倒瞬間會(huì)有一個(gè)很大的沖擊峰值。這些波形特征能幫你直觀(guān)判斷后續(xù)的閾值怎么設(shè)決策樹(shù)怎么分叉。3.3 采集數(shù)據(jù)與訓(xùn)練MLC模型接下來(lái)是采集各類(lèi)動(dòng)作的數(shù)據(jù)。工具界面里有DataLog功能可以直接點(diǎn)擊錄制我采集了靜止5分鐘、走路5分鐘、模擬跌倒5分鐘每類(lèi)動(dòng)作采集的樣本量盡量均衡避免后面訓(xùn)練出的模型偏向數(shù)據(jù)多的那類(lèi)。每個(gè)樣本都會(huì)被打上標(biāo)簽這些標(biāo)簽就是決策樹(shù)的訓(xùn)練依據(jù)。訓(xùn)練頁(yè)面里工具會(huì)自動(dòng)根據(jù)標(biāo)簽數(shù)據(jù)生成一個(gè)決策樹(shù)結(jié)構(gòu)。你可以調(diào)整樹(shù)的最大深度、葉子節(jié)點(diǎn)最小樣本數(shù)這些超參數(shù)。我試過(guò)用默認(rèn)參數(shù)模型效果就已經(jīng)很不錯(cuò)了在驗(yàn)證集上的準(zhǔn)確率在95%以上。如果你對(duì)準(zhǔn)確率不滿(mǎn)意可以增加“上下文特征窗”的長(zhǎng)度默認(rèn)窗長(zhǎng)是1秒提高到2秒后模型能更好地區(qū)分“跌倒”和“彎腰撿東西”這類(lèi)容易混淆的動(dòng)作。3.4 生成配置代碼并部署到硬件模型訓(xùn)練完成后點(diǎn)擊“生成配置”按鈕工具會(huì)產(chǎn)出一段C語(yǔ)言配置代碼和一份寄存器映射表。需要注意的是這段代碼主要是針對(duì)MLC寄存器的初始化不是完整的工程項(xiàng)目需要你自己把它嵌入到主控的初始化流程里。在NUCLEO-F401RE上我先初始化I2C總線(xiàn)然后把生成的配置數(shù)組通過(guò)I2C逐次寫(xiě)入LSM6DSOX的寄存器最后使能MLC中斷。核心代碼大概是這樣/* 將工具生成的MLC配置數(shù)組寫(xiě)入傳感器 */ for (uint16_t i 0; i sizeof(mlc_config_register_array) / 2; i) { uint8_t reg_addr mlc_config_register_array[i][0]; uint8_t reg_val mlc_config_register_array[i][1]; i2c_write_reg(LSM6DSOX_I2C_ADDR, reg_addr, reg_val); } /* 使能MLC中斷輸出 */ uint8_t int1_ctrl_reg read_reg(LSM6DSOX_ADDR, LSM6DSOX_INT1_CTRL); int1_ctrl_reg | 0x01; // 使能MLC_INT1中斷 write_reg(LSM6DSOX_ADDR, LSM6DSOX_INT1_CTRL, int1_ctrl_reg);部署完成后我做了幾次真實(shí)的跌倒測(cè)試傳感器都能準(zhǔn)確觸發(fā)中斷MCU讀取到中斷后立即通過(guò)串口輸出跌倒報(bào)警。整個(gè)流程從打開(kāi)瀏覽器到跑通demo確實(shí)控制在十分鐘以?xún)?nèi)。這個(gè)速度放在以前用寄存器手冊(cè)手動(dòng)配置至少要半天起步。3.5 數(shù)據(jù)鏈路與網(wǎng)絡(luò)層面的對(duì)接這個(gè)工具的另一個(gè)亮點(diǎn)是提供了MQTT和HTTP示例代碼方便把結(jié)果上報(bào)上云。目前做AIoT項(xiàng)目傳感器端負(fù)責(zé)判斷“發(fā)生了什么”MCU負(fù)責(zé)決定“要不要上報(bào)”云端負(fù)責(zé)“匯總?cè)譅顟B(tài)”。三層分工最合理。我的建議是傳感器節(jié)點(diǎn)的輸出結(jié)果采用輕量級(jí)協(xié)議上報(bào)功耗控制得好實(shí)時(shí)性也有保障。如果是邊緣計(jì)算網(wǎng)關(guān)場(chǎng)景多個(gè)傳感器節(jié)點(diǎn)的結(jié)果可以先匯聚到一起再統(tǒng)一上送云端這樣能大幅減少無(wú)效報(bào)文的傳輸。4. 智能傳感器調(diào)試的常見(jiàn)問(wèn)題與排查經(jīng)驗(yàn)4.1 數(shù)據(jù)不對(duì)或沒(méi)有中斷響應(yīng)的排查清單我在用這套方案的過(guò)程中踩過(guò)不少坑。下面是幾個(gè)典型問(wèn)題和排查思路。問(wèn)題現(xiàn)象可能原因排查思路與解決方法傳感器沒(méi)有任何輸出I2C地址錯(cuò)誤或接線(xiàn)松動(dòng)檢查地址LSM6DSOX默認(rèn)地址是0x6A如果SA0引腳接高電平會(huì)變成0x6B先用I2C掃描工具確認(rèn)中斷一直不觸發(fā)中斷引腳配置錯(cuò)誤檢查MLC輸出是否映射到了INT1引腳確認(rèn)INT1_CTRL寄存器對(duì)應(yīng)位已置1跌倒檢測(cè)頻繁誤報(bào)訓(xùn)練樣本不均衡重新采集數(shù)據(jù)盡量讓各類(lèi)動(dòng)作樣本數(shù)量接近增加“日常動(dòng)作”的負(fù)樣本數(shù)量傳感器功耗異常偏高ODR配置過(guò)高如果只是做低頻狀態(tài)識(shí)別把ODR從208Hz降到52Hz功耗能降80%以上決策樹(shù)準(zhǔn)確率不夠數(shù)據(jù)標(biāo)注不準(zhǔn)確清洗標(biāo)注數(shù)據(jù)刪除邊界模糊的樣本或者延長(zhǎng)數(shù)據(jù)采集時(shí)長(zhǎng)4.2 部署過(guò)程最常見(jiàn)的三個(gè)“坑”第一個(gè)坑是寄存器地址沖突。工具生成的配置代碼是基于特定固件版本的如果你手里的芯片是舊版本個(gè)別寄存器地址可能有差異。我遇到過(guò)在網(wǎng)頁(yè)工具上一切正常部署到實(shí)際芯片后MLC完全不工作的情況最后對(duì)比數(shù)據(jù)手冊(cè)才發(fā)現(xiàn)有一個(gè)保留寄存器地址在新版本固件中定義了新功能舊芯片上寫(xiě)入會(huì)失敗。解決辦法是部署前先讀取WHO_AM_I寄存器確認(rèn)傳感器型號(hào)和固件版本。第二個(gè)坑是中斷服務(wù)函數(shù)的設(shè)計(jì)。MLC中斷是脈沖式的在中斷服務(wù)函數(shù)里做串口打印和日志寫(xiě)入是大忌。我吃過(guò)一次虧中斷服務(wù)函數(shù)里用了Hal_Delay延遲結(jié)果后面的中斷全部被阻塞。正確做法是中斷服務(wù)函數(shù)里只置一個(gè)標(biāo)志位具體的業(yè)務(wù)處理放到主循環(huán)里執(zhí)行。第三個(gè)坑是數(shù)據(jù)歸一化處理。MLC模型內(nèi)部對(duì)輸入數(shù)據(jù)有歸一化要求你在采集數(shù)據(jù)時(shí)用的是原始值但部署后如果沒(méi)有按同樣方式進(jìn)行歸一化模型效果會(huì)大打折扣。工具生成的配置代碼其實(shí)已經(jīng)包含歸一化系數(shù)了但如果你導(dǎo)出了模型參數(shù)再手工修改配置數(shù)組很容易漏掉這一步。4.3 從傳感器到云端的聯(lián)調(diào)經(jīng)驗(yàn)從傳感器到云端全鏈路聯(lián)調(diào)時(shí)我建議先用串口抓傳感器直接輸出的結(jié)果驗(yàn)證傳感器側(cè)邏輯沒(méi)問(wèn)題再接入MCU最后才連云端。這個(gè)順序能避免“問(wèn)題到底出在哪一層”的困境。我自己的調(diào)試習(xí)慣是先在Web工具里打開(kāi)“傳感器日志”模式直接觀(guān)察MLC輸出結(jié)果是否正確再進(jìn)入MCU代碼調(diào)試。另外如果你用MQTT協(xié)議上報(bào)傳感器結(jié)果建議在MQTT的Topic設(shè)計(jì)上按照“設(shè)備類(lèi)型/設(shè)備ID/事件類(lèi)型”做分級(jí)這樣云端訂閱和權(quán)限管理都會(huì)清晰很多。傳感器事件附帶時(shí)間戳也很有必要否則在網(wǎng)絡(luò)抖動(dòng)延遲上報(bào)的場(chǎng)景下云端無(wú)法判斷事件發(fā)生的真實(shí)先后順序。5. 關(guān)于智能傳感器后續(xù)擴(kuò)展的個(gè)人想法這套工具給我最大的觸動(dòng)是ST把“傳感器算法專(zhuān)家”的能力做成了可視化網(wǎng)頁(yè)讓不懂寄存器細(xì)節(jié)的開(kāi)發(fā)者也能用上MLC和FSM。但工具始終是工具底層的數(shù)據(jù)意識(shí)、模型意識(shí)還得自己培養(yǎng)。我建議你在做AIoT項(xiàng)目時(shí)不要因?yàn)檫@個(gè)工具好用就省略數(shù)據(jù)記錄這一環(huán)把傳感器原始數(shù)據(jù)和MLC結(jié)果同時(shí)保存下來(lái)回頭調(diào)優(yōu)模型時(shí)會(huì)有大用處。如果你還沒(méi)用過(guò)這個(gè)Web工具我的建議是別光看文檔直接拿個(gè)傳感器板子打開(kāi)網(wǎng)頁(yè)把整個(gè)流程跑一遍。從選模板、采集數(shù)據(jù)、訓(xùn)練模型到部署到硬件十分鐘的動(dòng)手體驗(yàn)比讀十篇評(píng)測(cè)文都有用。跑通了一個(gè)最簡(jiǎn)單的demo之后再想往工業(yè)監(jiān)測(cè)、穿戴健康、智能家居這些具體場(chǎng)景走心里就有底了。