在 CH32V003 上,神經(jīng)網(wǎng)絡(luò)通過量化感知訓(xùn)練表現(xiàn)出色,這讓我很受鼓舞,我想知道這可以走多遠。我們可以將神經(jīng)網(wǎng)絡(luò)壓縮多少,同時仍然在 MNIST 數(shù)據(jù)集上實現(xiàn)良好的測試精度?當(dāng)談到絕對低端微控制器時,幾乎沒有比 應(yīng)廣單片機Padauk 8 位微控制器更引人注目的目標(biāo)了。這些微控制器針對最簡單和成本最低的應(yīng)用進行了優(yōu)化。該產(chǎn)品組合中最小的設(shè)備 PMS150C 具有 1024 個 13 位字一次性可編程內(nèi)存和 64 字節(jié) RAM,比 CH32V003 小一個數(shù)量級以上。此外,它具有基于專有累加器的 8 位架構(gòu),而不是功能更強大的 RISC-V 指令集。
是否也可以在應(yīng)廣單片機PMS150C 上實現(xiàn)可以對手寫數(shù)字進行分類的 MNIST 推理引擎?
在 CH32V003 上,我使用了從 28×28 縮小到 16×16 的 MNIST 樣本,這樣每個樣本占用 256 字節(jié)的存儲空間。如果有 16kb 的閃存可用,這是完全可以接受的,但如果只有 1kword 的 rom,這就太多了。因此,我首先將數(shù)據(jù)集縮小到 8×8 像素。
上圖顯示了兩種分辨率下數(shù)據(jù)集中的幾個樣本。在 16×16 下仍然很容易區(qū)分不同的數(shù)字。在 8×8 下仍然可以猜出大多數(shù)數(shù)字,但會丟失大量信息。
令人驚訝的是,仍然可以訓(xùn)練機器學(xué)習(xí)模型以令人印象深刻的準(zhǔn)確度識別這些非常低分辨率的數(shù)字。重要的是要記住,測試數(shù)據(jù)集包含 10000 張模型在訓(xùn)練期間看不到的圖像。非常小的模型準(zhǔn)確識別這些圖像的唯一方法確實是識別常見模式。我訓(xùn)練了許多不同的網(wǎng)絡(luò)組合,以了解網(wǎng)絡(luò)內(nèi)存占用和可實現(xiàn)準(zhǔn)確度之間的權(quán)衡。
參數(shù)探索
上圖顯示了我的超參數(shù)探索實驗的結(jié)果,比較了具有不同權(quán)重配置和量化級別(從 1 位到 4 位)的模型,用于 8×8 和 16×16 的輸入圖像。最小的模型必須在沒有數(shù)據(jù)增強的情況下進行訓(xùn)練,否則它們不會收斂。
同樣,測試準(zhǔn)確度和網(wǎng)絡(luò)的內(nèi)存占用之間存在明顯的關(guān)系。增加內(nèi)存占用可將準(zhǔn)確度提高到一定程度。對于 16×16,在上限可以實現(xiàn)約 99% 的準(zhǔn)確度,而對于 8×8 測試樣本,可以實現(xiàn)約 98.5% 的準(zhǔn)確度。考慮到 8×8 的信息損失很大,這仍然令人印象深刻。
對于小型模型,8×8 的準(zhǔn)確度比 16×16 更高。原因是第一層的大小在小模型中占主導(dǎo)地位,而對于 8×8 輸入,該大小減少了 4 倍。
令人驚訝的是,即使在小到半千字節(jié)的模型上,也可以實現(xiàn)超過 90% 的測試準(zhǔn)確率。這意味著它可以裝入微控制器的代碼內(nèi)存中!既然已經(jīng)確定了一般可行性,我需要進一步調(diào)整以適應(yīng) MCU 的限制。
訓(xùn)練目標(biāo)模型
由于 RAM 限制為 64 字節(jié),因此模型結(jié)構(gòu)在推理過程中必須使用最少數(shù)量的潛在參數(shù)。我發(fā)現(xiàn)可以使用窄至 16 的層。這會將推理期間的緩沖區(qū)大小減少到僅 32 字節(jié),一個輸入緩沖區(qū)和一個輸出緩沖區(qū)各 16 字節(jié),其余 32 字節(jié)用于其他變量。8×8 輸入模式直接從 ROM 讀取。
此外,我使用了間距不規(guī)則的 2 位權(quán)重(-2、-1、1、2),以便簡化推理代碼的實現(xiàn)。我還跳過了層規(guī)范化,而是使用恒定移位來重新調(diào)整激活。這些變化略微降低了準(zhǔn)確性。最終的模型結(jié)構(gòu)如下所示。
綜合考慮,我最終得到了一個準(zhǔn)確率為 90.07% 的模型,總共 3392 位(0.414 千字節(jié)),1696 個權(quán)重,如下面的日志所示。右側(cè)面板顯示訓(xùn)練模型的第一層權(quán)重,它直接掩蓋了測試圖像中的特征。與更高精度的模型相比,每個通道似乎同時結(jié)合了許多特征,看不到任何可辨別的模式。
在微控制器上的實現(xiàn)
在第一次迭代中,我使用了 Padauk 微控制器的稍大版本 PFS154。該設(shè)備的 ROM 和 RAM 是原來的兩倍,并且可以重新刷新,這極大地簡化了軟件開發(fā)。推理代碼的 C 版本(包括調(diào)試輸出)幾乎開箱即用。下面,您可以看到預(yù)測和標(biāo)簽,包括最后一層輸出。
void
fc_innerloop_mem(
uint8_t
loops) {
sum = 0;
do
{
weightChunk = *weightidx++;
__asm
idxm a, _activations_idx
inc _activations_idx+0
t0sn _weightChunk, #6
sl a ;
if
(weightChunk & 0x40) in = in+in;
t0sn _weightChunk, #7
neg a ;
if
(weightChunk & 0x80) in =-in;
add _sum+0,a
addc _sum+1
sl a
subc _sum+1
... 3x more ...
__endasm;
}
while
(--loops);
int8_t
sum8 = ((
uint16_t
)sum)>>3;
// Normalization
sum8 = sum8 < 0 ? 0 : sum8;
// ReLU
*output++ = sum8;
}
將所有內(nèi)容壓縮以適合較小的 PMS150C 是另一回事。用 C 語言對這些設(shè)備進行編程時的一個主要問題是,每個函數(shù)調(diào)用都會消耗 RAM 用于返回堆棧和函數(shù)參數(shù)
應(yīng)廣單片機產(chǎn)品應(yīng)用領(lǐng)域
玩具類:
RF/IR遙控直升飛機,遙控車,PS游戲機,兒童智能玩具,動物語音玩具,游戲方向盤,兒童學(xué)習(xí)機等
家電類:
電磁爐、電炒鍋、電飯煲、熱水壺,健康秤、冰箱控制系統(tǒng)、遙控器、電風(fēng)扇、洗衣機控制模塊、消毒柜、智能家居系統(tǒng),遙控?zé)艟叩?/p>
電子消費類:
電子萬年歷、溫度濕度計、跑步計速器、按摩器、數(shù)碼復(fù)讀錄音、筆電子禮品、電子密碼鎖,鎳氫,鋰電池充電器,超聲波測距,防盜報警器,燈飾控制,舵機
其它:
智能溫濕度記錄儀、智能溫控器、計時器、計數(shù)器、電機調(diào)速控制器、鼠標(biāo)、鍵盤、移動存貯盤