一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何把Tengine Python API移植到Tengine Lite上

電子設(shè)計(jì) ? 來(lái)源:電子設(shè)計(jì) ? 作者:電子設(shè)計(jì) ? 2020-12-15 00:30 ? 次閱讀

大佬說(shuō)選擇移植Tengine Python API這個(gè)任務(wù),一方面是因?yàn)樗白鲞^(guò)涉及Python和C++/C交互的開(kāi)源項(xiàng)目工作,如 MXNet 中DLPack的Python API和他自己的開(kāi)源項(xiàng)目 MobulaOP,這些工作讓他踩了不少的坑;另一方面是因?yàn)樗J(rèn)為,了解一個(gè)框架需要先把例子跑起來(lái), 就像學(xué)習(xí)一門(mén)新的編程語(yǔ)言要先跑通它的Hello World程序。通過(guò)這次任務(wù),可以了解基于Tengine Lite的圖像分類(lèi)實(shí)現(xiàn),對(duì)TengineLite有一個(gè)初始的、直觀的感受。

以下為大佬第一人稱(chēng)自述/~

初探源碼

這個(gè)任務(wù)的工作可以用一句話(huà)來(lái)概括: 在Tengine跑起Python例子, 再在Tengine Lite跑起同樣的例子。

第一步需要找到Tengine Python API的例子。但Tengine沒(méi)有的Python例子, 也沒(méi)有Python API的文檔。想從單元測(cè)試入手,但也沒(méi)有Python API的單元測(cè)試,難怪移植Python API的任務(wù)難度比移植C++ API的任務(wù)難度高。還有什么方法可以了解Python API的用法呢? 閱讀源碼。Tengine的Python API放在pytengine文件夾, 里面有八個(gè)模塊,分別是:base、context、device、 graph、libinfo、node、tengine和tensor,可以重點(diǎn)關(guān)注base, graph和tensor。

從base.py源碼中可以看出Tengine使用ctypes的形式進(jìn)行Python和C++/C的交互,把動(dòng)態(tài)鏈接庫(kù)libtengine.so讀取后保存到變量/_LIB中,通過(guò)/_LIB.可以調(diào)用Tengine的C API. graph.py實(shí)現(xiàn)計(jì)算圖部分的API,tensor.py實(shí)現(xiàn)了作為輸入和輸出的張量API。

編譯和導(dǎo)入模塊

找到Python API代碼的位置后,編譯Tengine,并嘗試在Python中導(dǎo)入tengine模塊。從libinfo.py中可以了解到,Tengine Python API會(huì)在Python API目錄和環(huán)境變量LD/_LIBRARY/_PATH所指向的目錄中,查找動(dòng)態(tài)鏈接庫(kù)libtengine.so.這時(shí)遇到了第一個(gè)Bug,我用的操作系統(tǒng)沒(méi)有定義LD/_LIBRARY/_PATH這個(gè)環(huán)境變量,而API里直接用下標(biāo)訪(fǎng)問(wèn)的形式取這個(gè)環(huán)境變量的值,出現(xiàn)了KeyError的錯(cuò)誤。改成os.environ.get('LD/_LIBRARY/_PATH', '')即可。設(shè)置好動(dòng)態(tài)鏈接庫(kù)的路徑后,可以成功導(dǎo)入pytengine模塊了。

編寫(xiě)Python分類(lèi)示例

Tengine提供C++/C的分類(lèi)示例代碼,在examples目錄下,可以作為編寫(xiě)Python例子時(shí)的參考。其中,classification.cpp用了Tengine的C++ API,比C API多了Net類(lèi)的封裝,Net類(lèi)封裝了對(duì)于計(jì)算圖Graph的操作。而classification/_old/_api.cpp用的是Tengine的C API. 由于Tengine Python API調(diào)用的是Tengine C API,因此可以拿classification/_old/_api.cpp作為參考。Tengine Python API封裝得很簡(jiǎn)潔,很容易能找到每個(gè)Python函數(shù)調(diào)用的C函數(shù)。C++分類(lèi)示例代碼和Python API的代碼互相對(duì)照,就可以寫(xiě)出Python分類(lèi)示例的代碼。寫(xiě)完后就可以嘗試運(yùn)行了。

運(yùn)行Python分類(lèi)示例

運(yùn)行Python分類(lèi)示例并不順利,一開(kāi)始就在構(gòu)建計(jì)算圖上出錯(cuò)了。定位到Python API的源碼后, 發(fā)現(xiàn)是在以下兩行出錯(cuò)。

# pytengine/tengine/graph.py:L24-L25 
params = [ c_str(item) for item in kwarg] 
self.graph = _LIB.create_graph(ctypes.c_void_p(context), c_str(model), *params)

create/_graph有三個(gè)參數(shù): 第一個(gè)參數(shù)context是模型執(zhí)行的上下文,第二個(gè)參數(shù)是模型的格式,第三個(gè)參數(shù)是模型的文件名。這兩行代碼看起來(lái)沒(méi)什么毛病,和C++例子里的調(diào)用方式是一模一樣的。但出錯(cuò)的原因就在給變量params賦值的這一行,里面的item是一個(gè)臨時(shí)變量,當(dāng)這條語(yǔ)句結(jié)束時(shí),item離開(kāi)了作用域就被釋放了。而c/_str(item)是指向原來(lái)item的位置,變成了一個(gè)野指針。為了解決這個(gè)問(wèn)題,可以把該行改為params = [ c/_str(kwarg[i]) for i in range(len(kwarg)) ],此時(shí)c/_str(kwarg[i])指向的是變量kwargs中存儲(chǔ)的值,變量kwargs在調(diào)用函數(shù)create/_graph時(shí)仍在作用域內(nèi)。

另外遇到的一個(gè)復(fù)雜的問(wèn)題和Tensor類(lèi)有關(guān), pytengine的Tensor類(lèi)還不完善,無(wú)法取出Tensor里的數(shù)據(jù).。對(duì)照C語(yǔ)言寫(xiě)的例子修改Tensor的buf函數(shù),得到數(shù)據(jù)內(nèi)存地址,占用的內(nèi)存大小,類(lèi)型,尺寸后,轉(zhuǎn)換為NumPy數(shù)組。 需要注意一下Tengine Lite前端的執(zhí)行步驟:

# 建立計(jì)算圖并讀取模型文件
tm_file graph = tg.Graph(None, 'tengine', tm_file) 
# 取出輸入
Tensor input_tensor = graph.getInputTensor(0, 0) 
# 設(shè)置輸入Tensor的尺寸 
dims = [1, 3, img_h, img_w] 
input_tensor.shape = dims
# 預(yù)先運(yùn)行以分配資源, 必須加上 
graph.preRun() 
# 設(shè)置輸入數(shù)據(jù)的內(nèi)存地址, 這里的data是尺寸為(3, img_h, img_w)的NumPy數(shù)組. 注意: 這里不會(huì)檢查shape 
input_tensor.buf = data
# 以同步方式讓網(wǎng)絡(luò)進(jìn)行推斷(前向傳播), 其中1表示使用同步的方式 
graph.run(1) # 1 is blocking 
# 取出輸出的Tensor 
output_tensor = graph.getOutputTensor(0, 0) 
# 將Tensor轉(zhuǎn)為NumPy數(shù)組 
output = np.array(output_tensor.buf)

把這些問(wèn)題解決后,就能在Tengine上運(yùn)行Python示例了。

需要注意的是,Tengine Lite和Tengine在做推斷前,都需要調(diào)用preRun()函數(shù)對(duì)資源進(jìn)行分配,這是必須要調(diào)用的。 雖然現(xiàn)在的Python API用起來(lái)有點(diǎn)復(fù)雜,但相信之后會(huì)封裝得更好的。

從Tengine到Tengine Lite

在Tengine上成功運(yùn)行Python示例后,移植就變得方便了。直接把pytengine文件夾下的所有代碼, 以及Python分類(lèi)示例復(fù)制粘貼到Tengine Lite中,將動(dòng)態(tài)庫(kù)名稱(chēng)從libtengine.so改為libtengine-lite.so, 然后運(yùn)行Python分類(lèi)示例。不出意料,出錯(cuò)了。 原因是Tengine Lite在設(shè)置輸入Tensor的數(shù)據(jù)內(nèi)存地址時(shí),也會(huì)檢查數(shù)據(jù)的大小,而之前的Python API的數(shù)據(jù)大小的計(jì)算是錯(cuò)誤的。 修復(fù)Bug后, 成功在Tengine Lite上運(yùn)行圖像分類(lèi)示例。移植完成。不得不夸一下Tengine Lite的C API兼容性做得真好!

在EAIDK-310上運(yùn)行Tengine Lite的Python圖像分類(lèi)示例

之前參加OPEN AI LAB的活動(dòng),得到了一塊EAIDK-310開(kāi)發(fā)板, 剛好可以在上面進(jìn)行測(cè)試。
這里使用可愛(ài)的虎貓(Tiger Cat)作為測(cè)試圖片,模型采用MobileNet。 圖片和模型都可以在Tengine項(xiàng)目的頁(yè)面中找到鏈接 (Tengine快速上手指南)。

下載代碼

[openailab@localhost proj]$ git clone https://github.com/OAID/Tengine 
# 進(jìn)入Tengine的目錄 
cd Tengine 
[openailab@localhost Tengine]$ git branch 
* tengine-lite

當(dāng)前Tengine的默認(rèn)分支是Tengine Lite。

2. 編譯Tengine Lite

mkdir build 
cd build 
cmake .. 
make -j2

注意不要把編譯線(xiàn)程數(shù)設(shè)太大,因?yàn)樵谧詈缶幾gMobileNet SSD例子時(shí)消耗顯存比較多。六分鐘多可以編譯完。

3. 配置Tengine Lite的Python API編輯/home/openailab/.bashrc,再最后一行后面加入:

export TENGINE_LITE_PATH=/home/openailab/proj/Tengine 
export PYTHONPATH=$PYTHONPATH:$TENGINE_LITE_PATH/pytengine 
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TENGINE_LITE_PATH/build/src/

環(huán)境變量TENGINE_LITE_PATH設(shè)置為T(mén)engine Lite的根目錄路徑, 設(shè)置好后重新打開(kāi)終端。 打開(kāi)Python, 能成功導(dǎo)入tengine。

[openailab@localhost examples]$ python 
Python 3.6.5 (default, Mar 29 2018, 17:45:40) 
[GCC 8.0.1 20180317 (Red Hat 8.0.1-0.19)] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import tengine

4. 將三個(gè)文件cat.jpg/, mobilenet.tmfile/, synset/_words.txt放在examples的目錄下, 文件結(jié)構(gòu)如下所示:

[openailab@localhost examples]$ pwd 
/home/openailab/proj/Tengine/examples

[openailab@localhost examples]$ tree 
. 
├── cat.jpg 
├── classification.py 
├── mobilenet.tmfile 
├── synset_words.txt

5. 運(yùn)行examples文件夾下的圖像分類(lèi)示例classification.py

[openailab@localhost examples]$ python classification.py 
n02123159 tiger cat 8.5975923538208 
n02119022 red fox, Vulpes vulpes 7.954988956451416 
n02119789 kit fox, Vulpes macrotis 7.867891311645508 
n02113023 Pembroke, Pembroke Welsh corgi 7.427407264709473 
n02123045 tabby, tabby cat 6.364651679992676

由此,就能夠在Tengine Lite上正確預(yù)測(cè)出虎貓啦 : )

下一步工作

對(duì)于Tengine Lite Python API,我覺(jué)得在API設(shè)計(jì)方面可以進(jìn)一步改進(jìn)。比如把數(shù)據(jù)預(yù)處理, 計(jì)算圖構(gòu)建等操作隱藏起來(lái),比如:

image = cv2.imread('./cat.jpg') 
model = tg.Model(tm_file) 
pred = model(image)

這樣可以減少出錯(cuò)概率, 一些錯(cuò)誤比如忘記對(duì)數(shù)據(jù)做預(yù)處理,使用的數(shù)據(jù)內(nèi)存分布(NCHW還是NHWC)不正確,忘記調(diào)用prerun。

本次Tengine Python API移植任務(wù),大佬做的工作是編寫(xiě)一個(gè)Python的圖像分類(lèi)示例,在Tengine上跑通代碼,再將pytengine移植(復(fù)制)到Tengine Lite上, 再在Tengine Lite上跑通代碼,其中還修復(fù)了pytengine中的一些bug。

更多Tengine相關(guān)內(nèi)容請(qǐng)關(guān)注Tengine-邊緣AI推理框架專(zhuān)欄。

審核編輯 黃昊宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • python
    +關(guān)注

    關(guān)注

    56

    文章

    4822

    瀏覽量

    85896
  • Tengine
    +關(guān)注

    關(guān)注

    1

    文章

    47

    瀏覽量

    3014
收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    蜂鳥(niǎo)E203的NICE接口如何移植其他RISCV核

    蜂鳥(niǎo)E203的NICE接口移植其他RISCV核
    發(fā)表于 03-07 08:49

    使用Python API在OpenVINO?中創(chuàng)建了用于異步推理的自定義代碼,輸出張量的打印結(jié)果會(huì)重復(fù),為什么?

    使用 Python* API 在 OpenVINO? 中創(chuàng)建了用于異步推理的自定義代碼。 遇到輸出張量的打印結(jié)果會(huì)重復(fù)的問(wèn)題,即使輸入圖像不同。
    發(fā)表于 03-06 07:53

    DLP6500能否用Python編程進(jìn)行開(kāi)發(fā),是否有API接口?

    本人第一次接觸DLP的開(kāi)發(fā)板,想知道DLP6500這款板子能否用Python編程進(jìn)行開(kāi)發(fā),是否有API接口?
    發(fā)表于 02-28 06:58

    如何將RT-Thread移植NXP MCUXPressoIDE

    RT-Thread默認(rèn)支持的IDE只有IAR 和 Keil, 那如何將RT-Thread移植NXP MCUXPressoIDE呢?本文內(nèi)容比較簡(jiǎn)單但稍有瑣碎,希望對(duì)有需要的小伙伴有所幫助。
    的頭像 發(fā)表于 02-13 10:37 ?1600次閱讀
    如何將RT-Thread<b class='flag-5'>移植</b><b class='flag-5'>到</b>NXP MCUXPressoIDE<b class='flag-5'>上</b>

    將基于PC的MP3播放器軟件移植ADSP-21262 SHARC處理器

    電子發(fā)燒友網(wǎng)站提供《將基于PC的MP3播放器軟件移植ADSP-21262 SHARC處理器.pdf》資料免費(fèi)下載
    發(fā)表于 01-03 14:54 ?0次下載
    將基于PC的MP3播放器軟件<b class='flag-5'>移植</b><b class='flag-5'>到</b>ADSP-21262 SHARC處理器<b class='flag-5'>上</b>

    在設(shè)備利用AI Edge Torch生成式API部署自定義大語(yǔ)言模型

    MediaPipe LLM Inference API 讓開(kāi)發(fā)者們能夠?qū)⒁恍┳钍軞g迎的 LLM 部署設(shè)備?,F(xiàn)在,我們很高興能進(jìn)一步拓展對(duì)模型的支持范圍,并讓大家部署設(shè)備,而且具
    的頭像 發(fā)表于 11-14 10:23 ?837次閱讀
    在設(shè)備<b class='flag-5'>上</b>利用AI Edge Torch生成式<b class='flag-5'>API</b>部署自定義大語(yǔ)言模型

    如何利用pythonAPI查詢(xún)IP地址?

    Python中,直接查詢(xún)IP地址的地理位置或詳細(xì)信息(如所屬?lài)?guó)家、城市等)通常需要依賴(lài)外部API服務(wù),因?yàn)?b class='flag-5'>Python標(biāo)準(zhǔn)庫(kù)本身不提供直接查詢(xún)IP地址地理位置的功能。以下是一個(gè)使用requests
    發(fā)表于 08-28 11:55

    手冊(cè)新 |迅為RK3568開(kāi)發(fā)板NPU例程測(cè)試

    rknpu2工具套件使用 第5章 rknn-model-zoo例程演示 5.1 模型下載和模型轉(zhuǎn)換 5.2 Python API推理 5.3 C API 推理 第6章 rknn-model-zoo模型推理
    發(fā)表于 08-12 11:03

    是否能將libwebsokets移植ESP8266利用libwebsokets進(jìn)行網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)?

    1. 如題目,請(qǐng)問(wèn)是否能將 libwebsokets 移植 ESP8266 利用 libwebsokets進(jìn)行網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)? 2. libwebsokets 是純C實(shí)現(xiàn),如何設(shè)置ESP8266
    發(fā)表于 07-22 06:22

    0.9.3的sdk的程序移植1.0的sdk,重啟后一直掛機(jī)的原因?

    0.9.3的sdk原來(lái)的程序移植1.0的sdk,下載完成后,不斷電,程序運(yùn)行正常,但重啟后一直掛機(jī)。 load 0x40100000, len 816, room 16 1
    發(fā)表于 07-12 07:28

    將ADF移植RTOS大概都需要哪些步驟?一般移植周期多久呢?

    1 ADF是免費(fèi)的開(kāi)源軟件嗎? 2 將ADF移植RTOS大概都需要哪些步驟?一般移植周期多久呢?
    發(fā)表于 06-28 08:03

    如何移植http/https serversoftAP?

    網(wǎng)頁(yè)服務(wù)器移植 worksapceesp-idfexampleswifigetting_startedsoftAP 可以通過(guò)網(wǎng)頁(yè)進(jìn)行配置 現(xiàn)在是一點(diǎn)思路都沒(méi)有,各種 大神/牛哥,給點(diǎn)指導(dǎo),謝謝了
    發(fā)表于 06-19 06:14

    第四講:?jiǎn)纹瑱C(jī)STC89C52+RA8889驅(qū)動(dòng)控制彩屏 代碼移植范例(包含API接口)

    51單片機(jī)通過(guò)RA8889控制驅(qū)動(dòng)彩屏,移植API參考程序
    的頭像 發(fā)表于 06-06 13:59 ?1825次閱讀
    第四講:?jiǎn)纹瑱C(jī)STC89C52+RA8889驅(qū)動(dòng)控制彩屏 代碼<b class='flag-5'>移植</b>范例(包含<b class='flag-5'>API</b>接口)

    訊飛星火Lite API開(kāi)放免費(fèi)永久,星火Pro/Max API價(jià)格0.2元

    5月22日,科大訊飛宣布旗下訊飛星火Lite API完全免費(fèi)向公眾開(kāi)放,滿(mǎn)足在線(xiàn)聯(lián)網(wǎng)搜索及低算力推理與模型精調(diào)等特殊需求。同時(shí),訊飛星火Pro/Max API的定價(jià)則為每萬(wàn)tokens收取0.21元。
    的頭像 發(fā)表于 05-22 11:43 ?1924次閱讀

    STemWin移植STM32后無(wú)法顯示怎么解決?

    最近在玩STemWin,但是移植STM32后無(wú)法顯示,單步調(diào)試的時(shí)候進(jìn)入不了打點(diǎn)函數(shù),我用的是IAR,驅(qū)動(dòng)代碼沒(méi)有優(yōu)化,僅僅是想先用打點(diǎn)函數(shù)來(lái)實(shí)現(xiàn)一下看看效果,后續(xù)再做優(yōu)化,請(qǐng)教一下大神們,這個(gè)該怎么解決
    發(fā)表于 05-13 07:20