
歡迎關(guān)注【玩轉(zhuǎn)單片機(jī)與嵌入式】公眾號,關(guān)注后回復(fù)【嵌入式AI】可獲取更多免費(fèi)視頻和資料
這里是《賀老師講嵌入式AI》,我是《嵌入式AI:讓單片機(jī)學(xué)會思考》課程主理人,專注AI在MCU上的落地實(shí)踐。
一個(gè)聲音識別模型部署到 STM32 后,串口穩(wěn)定輸出:alarm = 0.99。工程師很容易把它翻譯成“模型有 99% 的把握聽到了報(bào)警聲”,然后寫下 if (score > 0.9f)。蜂鳴器、繼電器或者消息上報(bào)就此接通。
這樣是對的嗎?本文帶你來論證一下!
以“正常聲、報(bào)警聲、撞擊聲”三分類模型為例,最后一層先輸出三個(gè) logit。logit 可以理解為模型對各類別累積出來的原始證據(jù),它們可以是正數(shù),也可以是負(fù)數(shù),并不是概率。
logits= [-1.2, 4.6, 0.8]softmax(logits) = [0.003, 0.975, 0.022]argmax = 報(bào)警聲
Softmax 對這些數(shù)做指數(shù)變換和歸一化,讓三個(gè)輸出都落在 0 到 1 之間,并且總和等于 1。這里的 0.975 表示:在模型被要求從這三個(gè)類別中選一個(gè)時(shí),“報(bào)警聲”占據(jù)了絕大部分相對證據(jù)。它沒有證明輸入一定屬于這三個(gè)類別,也沒有證明同類輸入判斷 100 次就能對 97.5 次。
Softmax 有一個(gè)容易被忽略的限制:它必須把全部份額分給已知類別。把電鉆聲、風(fēng)噪或者麥克風(fēng)飽和后的方波送進(jìn)去,類別集合里即使沒有“未知”,結(jié)果仍然會被分配給正常聲、報(bào)警聲或撞擊聲。題目超出范圍,模型也不會主動(dòng)交白卷。

int8,串口中的原始整數(shù)不能直接當(dāng)百分比。應(yīng)先按量化參數(shù)反量化:real = scale × (q - zero_point)。有的模型輸出已經(jīng)是量化后的 Softmax,有的輸出仍是 logits;應(yīng)以模型輸出層和工具生成的張量信息為準(zhǔn)。把數(shù)值 100 打印成“100%”,不是置信度高,而是單位弄錯(cuò)了。模型準(zhǔn)確率和置信度校準(zhǔn)是兩項(xiàng)不同的檢查。準(zhǔn)確率回答“測試集總體對了多少”;校準(zhǔn)回答“模型說自己有 90% 把握的那些樣本,是否真的大約有 90% 判斷正確”。一個(gè)分類器可以準(zhǔn)確率不錯(cuò),同時(shí)對錯(cuò)誤答案過度自信。
準(zhǔn)備一份沒有參與訓(xùn)練、也沒有拿來挑模型的現(xiàn)場驗(yàn)證集。記錄每個(gè)窗口的最高分?jǐn)?shù)、預(yù)測類別和真實(shí)標(biāo)簽,再按 0.0~0.1、0.1~0.2……分桶。每個(gè)桶分別計(jì)算平均置信度和真實(shí)正確率。
如果 0.9~1.0 這一桶的平均分?jǐn)?shù)是 0.94,而真實(shí)正確率只有 0.76,模型就是過度自信。此時(shí)把報(bào)警閾值從 0.90 調(diào)到 0.95,只是在移動(dòng)一個(gè)未經(jīng)校準(zhǔn)的數(shù)字,不能自動(dòng)補(bǔ)上那 18 個(gè)百分點(diǎn)的差距。

現(xiàn)場表現(xiàn)比離線驗(yàn)證更差,通常還有三類工程原因。第一類是分布變化:訓(xùn)練時(shí)是安靜實(shí)驗(yàn)室,部署后增加了機(jī)柜回聲、電源紋波、安裝位置差異和設(shè)備老化。第二類是輸入鏈路不一致:PC 使用浮點(diǎn)歸一化,MCU 卻發(fā)生整型截?cái)唷⒋翱阱e(cuò)位、通道順序交換或量化參數(shù)錯(cuò)誤。第三類是類別集合不完整:訓(xùn)練集只有“正?!焙汀澳繕?biāo)事件”,現(xiàn)場大量似是而非的背景事件沒有被當(dāng)作困難負(fù)樣本。
這些問題不會因?yàn)?Softmax 輸出了 0.99 而消失。Softmax 衡量的是模型內(nèi)部的相對競爭,不是傳感器健康度、數(shù)據(jù)是否越界,也不是輸入是否來自訓(xùn)練分布。
閾值不是模型附件中的固定參數(shù),而是產(chǎn)品決策的一部分。下面以聲音報(bào)警為例,給出一條能直接執(zhí)行的標(biāo)定流程。
先定義錯(cuò)誤成本統(tǒng)計(jì)一次誤報(bào)會造成什么,一次漏報(bào)又會造成什么。只做日志標(biāo)記時(shí)可以偏向召回率;會停機(jī)、斷電或通知用戶時(shí),誤報(bào)成本顯著上升。沒有成本定義,“最優(yōu)閾值”沒有數(shù)學(xué)意義。
單獨(dú)保留現(xiàn)場標(biāo)定集覆蓋不同設(shè)備、不同安裝位置、不同環(huán)境和不同日期。訓(xùn)練集負(fù)責(zé)學(xué)參數(shù),驗(yàn)證集負(fù)責(zé)選模型,標(biāo)定集負(fù)責(zé)確定分?jǐn)?shù)如何進(jìn)入產(chǎn)品決策。三者混用會讓閾值對已見數(shù)據(jù)過度樂觀。
逐類掃描閾值不要給全部類別共用 0.8。對目標(biāo)類別從 0.50 到 0.99 掃描,記錄 TP、FP、FN、precision、recall,并計(jì)算業(yè)務(wù)代價(jià):cost(t)=C_fp×FP(t)+C_fn×FN(t)。選擇滿足安全約束且代價(jià)較低的閾值。
增加分差和未知拒識除了最高分 p1,同時(shí)檢查第二高分 p2。當(dāng) p1-p2 很小,說明兩個(gè)類別競爭激烈;當(dāng)輸入幅值、噪聲底或傳感器狀態(tài)越界,直接輸出 UNKNOWN,不要強(qiáng)行分類。
用連續(xù)窗口驗(yàn)證,不用單幀截圖最終評估單位應(yīng)與產(chǎn)品動(dòng)作一致。如果固件要求 5 個(gè)窗口中至少 3 個(gè)滿足條件,離線回放也必須按相同規(guī)則統(tǒng)計(jì)事件級誤報(bào)率、漏報(bào)率和觸發(fā)延遲,不能繼續(xù)拿單窗口準(zhǔn)確率代替。
typedef enum { AI_NORMAL, AI_CANDIDATE, AI_CONFIRMED, AI_UNKNOWN } ai_state_t;
typedef struct {
float top1;
float top2;
uint8_t class_id;
bool sensor_ok;
} ai_result_t;
bool is_alarm_candidate(const ai_result_t *r)
{
const float alarm_threshold = 0.93f; // 由現(xiàn)場標(biāo)定集確定
const float min_margin = 0.18f; // top1 與 top2 的最小分差
if (!r->sensor_ok) return false;
if (r->class_id != CLASS_ALARM) return false;
if (r->top1 < alarm_threshold) return false;
if ((r->top1 - r->top2) < min_margin) return false;
return true;
}代碼中的 0.93 和 0.18 只是參數(shù)位置示例,不能復(fù)制到另一個(gè)項(xiàng)目繼續(xù)使用。量化模型如果直接比較整數(shù)輸出,應(yīng)把實(shí)數(shù)閾值換算到對應(yīng)量化域,并注意飽和和取整;更穩(wěn)妥的做法是先反量化,再保留一份浮點(diǎn)日志用于離線復(fù)盤。
上線前至少保存這些字段:時(shí)間戳、原始或可回放特征、模型版本、top1 類別、top1 分?jǐn)?shù)、top2 分?jǐn)?shù)、傳感器健康狀態(tài)、最終狀態(tài)和人工確認(rèn)結(jié)果。沒有這組日志,誤報(bào)發(fā)生后只能反復(fù)調(diào)閾值;有了它,才能判斷問題究竟來自數(shù)據(jù)、模型、校準(zhǔn)還是業(yè)務(wù)規(guī)則。
模型分?jǐn)?shù)可以參與決策,但不能冒充可靠性證明。真正可用的 TinyML,不是讓串口打印一個(gè)漂亮的 0.99,而是知道這個(gè)數(shù)在什么數(shù)據(jù)上可信、在什么條件下拒絕回答,以及它如何經(jīng)過現(xiàn)場標(biāo)定后再進(jìn)入設(shè)備動(dòng)作。
On Calibration of Modern Neural Networks:區(qū)分分類準(zhǔn)確率與置信度校準(zhǔn),并介紹溫度縮放。
scikit-learn Probability calibration:可靠性圖、校準(zhǔn)集以及 sigmoid、isotonic、temperature scaling 的說明。
CMSIS-NN Softmax Functions:Cortex-M 上 int8、int16 和 uint8 Softmax 接口及量化參數(shù)。

END