書(shū)接上文(點(diǎn)此查看前文),我們橫向比較了在應(yīng)用TFLm引擎進(jìn)行模型文件導(dǎo)入時(shí)候,所使用的三種常用方式:
SD卡存儲(chǔ)結(jié)合文件系統(tǒng),
xxd小工具進(jìn)行文件的十六進(jìn)制轉(zhuǎn)換
以及使用匯編指令.incbin直接進(jìn)行模型導(dǎo)入。
可以說(shuō)各有所長(zhǎng),但是,當(dāng)我們需要頻繁地進(jìn)行模型的替換、更新時(shí),麻煩就出現(xiàn)了。xxd和.incbin的形式都需要重新編譯目標(biāo)工程,并下載到板子中。 當(dāng)我們的程序體量較大時(shí),即便不需要對(duì)全部工程進(jìn)行編譯(做到改啥編啥),但是,下載這一步,是無(wú)論如何不能跳過(guò)的,隨著最終鏡像大小的不同,所消耗的時(shí)間也會(huì)不同。而使用文件系統(tǒng)的方式,無(wú)形中增加了移植文件系統(tǒng)的工作量。
設(shè)計(jì)思路
為了克服這一問(wèn)題,小編在上一篇的結(jié)尾提出了一個(gè)新的方案,直接把flash看作一大塊空白存儲(chǔ)區(qū),并開(kāi)辟一個(gè)固定區(qū)域存放模型文件。這樣一來(lái),我們只需要在程序中將模型的讀取位置固定,無(wú)論模型是否更新,都能夠讀取最新的模型數(shù)據(jù),進(jìn)行后續(xù)處理。 而且小編也特意強(qiáng)調(diào)建議大家直接使用Nor Flash來(lái)實(shí)現(xiàn)這一操作。 以i.MX RT系列MCU為例說(shuō)明這樣做的優(yōu)勢(shì)。i.MX RT系列由于沒(méi)有片上Flash芯片,都通過(guò)外擴(kuò)Flash芯片存儲(chǔ)代碼。當(dāng)我們將啟動(dòng)方式調(diào)整為XIP,即從flash啟動(dòng)時(shí),芯片內(nèi)部的BootROM會(huì)幫我們配置初始化好這個(gè)片上的Flash芯片,而由于Nor Flash的特性,支持隨機(jī)的內(nèi)存訪問(wèn),也就是說(shuō),我們?cè)诔绦騼?nèi)部,可以直接通過(guò)指針的形式進(jìn)行訪問(wèn),甚至可以直接調(diào)用memcpy函數(shù)進(jìn)行數(shù)據(jù)的拷貝。 比起集成文件系統(tǒng)的方式,可以說(shuō)方便至極。不過(guò),也不是說(shuō)Nand Flash就不適合,只是處理起來(lái)會(huì)稍稍麻煩一點(diǎn),由于不支持隨機(jī)的讀操作,就要先拷貝到RAM區(qū)域再進(jìn)行操作。
設(shè)計(jì)實(shí)現(xiàn)
言歸正傳,為了方便進(jìn)行數(shù)據(jù)的管理,我們需要設(shè)計(jì)一套簡(jiǎn)單的管理邏輯,說(shuō)的專業(yè)一點(diǎn)就是為我們的數(shù)據(jù)添加一個(gè)幀頭,當(dāng)然,既然大道至簡(jiǎn),數(shù)據(jù)打包格式大致就是如下格式(可能有些簡(jiǎn)陋啊,大家見(jiàn)諒):
當(dāng)然為了能夠在程序中使用,我們?cè)俣x一個(gè)對(duì)應(yīng)的C語(yǔ)言形式來(lái)表達(dá),這里要用到C語(yǔ)言中0長(zhǎng)度數(shù)組的概念:
struct { uint32_t n, w, h , c; uint8_t data[0]; }
這樣一來(lái),我們就具象化了我們所設(shè)計(jì)的那個(gè)簡(jiǎn)單的數(shù)據(jù)打包協(xié)議。
下一步是如何將數(shù)據(jù)打包成我們要的樣子,這里要借助于Python來(lái)編寫(xiě)一個(gè)簡(jiǎn)單的腳本處理,并假設(shè)最終會(huì)生成一個(gè)二進(jìn)制文件,假設(shè)輸入一個(gè)多維數(shù)組results,首先構(gòu)建其幀頭,默認(rèn)維度不足4的數(shù)據(jù),用1補(bǔ)齊,保證最終的幀頭包含4個(gè)維度信息:
def save_to_bin(bin_name, results): shape = list(results[0].shape) element_size = [1] * (3 - len(shape)) + shape element_len = len(results) # shape is [N, H, W, C] bin_values = np.asarray([element_len] + element_size, dtype=np.uint32).tobytes() bin_values += results.tobytes() with open(bin_name, "wb") as f: f.write(bin_values) f.close()
聊到這兒,可能有同學(xué)會(huì)問(wèn)了,針對(duì)于tflite模型,我們往往只需要知道其首地址就好了,TFLm會(huì)處理那些長(zhǎng)度信息,我還有必要構(gòu)造幀頭嗎?這下給小編問(wèn)的有點(diǎn)啞口無(wú)言。馬上著手設(shè)計(jì)了第二種數(shù)據(jù)結(jié)構(gòu):
是的,針對(duì)于模型數(shù)據(jù)這一特殊的存在,可以設(shè)計(jì)出更加精簡(jiǎn)的表達(dá)格式,而且,我們知道tflite模型本身實(shí)際上已經(jīng)是二進(jìn)制文件的形式了,也就是說(shuō),可以直接拿過(guò)來(lái)使用,無(wú)需再做任何操作,直接燒寫(xiě)到固定地址即可。
那我們上面所設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)就毫無(wú)用武之地了嗎?當(dāng)然不是!小編做這些當(dāng)然都是有理由的啊。
大家想一想,運(yùn)行神經(jīng)網(wǎng)絡(luò)模型的時(shí)候,光有模型就可以了嗎?當(dāng)然不,我們還缺少輸入啊!如果你是攝像頭輸入,請(qǐng)?zhí)^(guò)這節(jié)。而如果是離線測(cè)試呢?需要大量加載靜態(tài)圖到內(nèi)存中,是不是和之前我們的分析就類似了。
每次更換測(cè)試數(shù)據(jù),依舊需要重新下載鏈接,那么按照本文提供的方案,也為數(shù)據(jù)設(shè)置一塊固定的區(qū)域,然后借助于上述save_to_bin代碼,將數(shù)據(jù)打包成固定格式,是不是就可以在程序中利用那個(gè)結(jié)構(gòu)體訪問(wèn)了呢?沒(méi)錯(cuò)!小編早就設(shè)計(jì)好了。
-
芯片
+關(guān)注
關(guān)注
459文章
52449瀏覽量
439919 -
mcu
+關(guān)注
關(guān)注
146文章
17955瀏覽量
365821 -
編譯
+關(guān)注
關(guān)注
0文章
678瀏覽量
33940
原文標(biāo)題:一種基于MCU的神經(jīng)網(wǎng)絡(luò)模型在線更新方案之?dāng)?shù)據(jù)處理篇
文章出處:【微信號(hào):NXP_SMART_HARDWARE,微信公眾號(hào):恩智浦MCU加油站】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
KaihongOS操作系統(tǒng)FA模型與Stage模型介紹
訓(xùn)練好的ai模型導(dǎo)入cubemx不成功怎么處理?
聆思CSK6大模型語(yǔ)音開(kāi)發(fā)板接入DeepSeek資料匯總(包含深度求索/火山引擎/硅基流動(dòng)華為昇騰滿血版)
如何將python文件導(dǎo)入到ROS系統(tǒng)中

txb0108 pspice模型怎么使用?
如何導(dǎo)入Altium Designer的原理圖和PCB?

評(píng)論