跳到主要內容

[Movidius神經運算棒]五步驟打造Intel Movidius NCS影像分類器

(Original post from Intel Movidius NCS blog: “Build an Image Classifier in 5 steps”:https://movidius.github.io/blog/ncs-image-classifier/


什麼是影像分類?

影像分類是電腦視覺的重要課題。目標在於把圖像中的某個主題或物體歸類到預先定義的類別中。現實生活中的影像分類問題是把印有各種物體的卡片拿給小孩子看,並讓他們分辨卡片上所印的東西是什麼。傳統的作法是讓機器具備一定的視覺感知能力,這有賴於使用特徵描述器的各種複雜電腦演算法,描述器像是邊緣、角落與顏色等等,來辨識或辨認影像中的一或多個物體。
深度學習採用另一個更有效率的做法來解決現實生活中的影像問題。它運用了多層彼此互聯的神經元,每一層都採用了特定的演算法去辨識或分類某個描述符(descriptor)。舉例來說,如果您想要對交通的[STOP]號誌進行分類的話,要用到深度神經網路 (DNN) 來偵測號誌的邊緣與邊界,第一層則是用來偵測邊角的數量、下一層則是偵測紅色、再下一層偵測紅色周圍的白色邊界,一直反覆執行下去。DNN可以把一個任務分配到執行單一檢算法的多個層,這樣可以處理大量的描述符,讓基於DNN的影像處理應用於現實生活中能更有效率。
作者/攝影  曾吉弘
時間  2小時
成本
難度 * * * * *
材料表
  • Raspberry Pi 3單板電腦
  • Intel Movidius神經計算棒

Layer 1: 邊緣偵測(八角形)
Layer 2: 邊緣附近的白色邊界
Layer 3: 紅色本體
Layer 4: “STOP”字樣
注意:上圖僅用於示範DNN如何辨識物體中的不同描述符,並非DNN用於分類STOP標示的正確呈現。
影像分類與物件偵測是不一樣的。分類是假設整張圖中只有一個物體,例如上述的幼童圖卡範例。另一方面,物件偵測可以在同一張圖中處理多個物體,並計算各物體在圖中的位置。

邊做邊學!

您會製作:
從資料夾中讀取單張影像並進行分類。

您會學到:

  • 如何使用預訓練的網路來進行影像分類
  • 如何使用Intel® Movidius™ NCS 的API框架來編寫程式

您會需要:

  • Intel Movidius Neural Compute Stick 神經運算棒 – 購買請按我
  • 32/64位元的桌上型/筆記型電腦,作業系統須為Ubuntu 16.04 (“開發機器”)
如果還沒做的話,請在您的開發機器上安裝完整的NCSDK。請參考Intel Movidius NCS Quick Start Guide上的安裝步驟來完成。

先看結果…

如果想先看看程式輸出結果的話,請用以下使令來取得範例程式 (NC App Zoo) 並執行
mkdir -p ~/workspace
cd ~/workspace
git clone https://github.com/movidius/ncappzoo
cd ncappzoo/apps/image-classifier
make run
make run 指令會下載並建置所有的相依檔案,例如預訓練網路、二元graph檔、ilsvrc資料集均值等。只有第一次執行時要先執行make run;後續只要執行 python3 image-classifier.py 就可以了。應該會看到類似以下的訊息:
 ——- predictions ——–
prediction 1 is n02123159 tiger cat
prediction 2 is n02124075 Egyptian cat
prediction 3 is n02113023 Pembroke, Pembroke Welsh corgi
prediction 4 is n02127052 lynx, catamount
prediction 5 is n02971356 carton

開始吧!

感謝NCSDK 完整的API framework,只需要幾行Python就可以完成影像分類器。以下是image-classifier.py 中一些需要調整的使用者參數::
  1. GRAPH_PATH:要進行推論的graph檔路徑
    • 預設值為 ~/workspace/ncappzoo/caffe/GoogLeNet/graph
  2. IMAGE_PATH:想要分類的影像路徑
    • 預設值為 ~/workspace/ncappzoo/data/images/cat.jpg
  3. IMAGE_DIM:所採用神經網路之影像尺寸規格
    • 例如 GoogLeNet 採用 224×224像素,AlexNet則是227×227像素
  4. IMAGE_STDDEV:您選用之神經網路所定義的標準差(scaling value)
    • 例如:GoogLeNet不採用任何比例因子,但InceptionV3的比例因子為128 (stddev = 1/128)
  5. IMAGE_MEAN:均值減法(Mean subtraction)是深度學習領域中常用的資料整理技巧。
    • 對ILSVRC資料集來說,B、G、R的平均值分別為102、117與123
請先由mvnc函式庫匯入mvncapi模組,才能順利使用NCSDK API framework。
import mvnc.mvncapi as mvnc

Step 1:開啟enumerated裝置

如同其他USB裝置,當您將NCS接上應用程式處理器 (執行Ubuntu的桌上型/筆記型電腦) 的USB埠,前者會被後者枚舉為一個USB裝置。我們可以呼叫API來檢視各個NCS裝置。
# Look for enumerated Intel Movidius NCS device(s); quit program if none found.
devices = mvnc.EnumerateDevices()
if len( devices ) == 0:
print( 'No devices found' )
quit()
您知道在同一個應用程式中,可以連接多個NCS神經運算棒來提高推論效能嗎?以下語法是運用API 呼叫單一NCS並開啟 (意即準備好操作).
# Get a handle to the first enumerated device and open it
device = mvnc.Device( devices[0] )
device.OpenDevice()

Step 2:將graph檔載入NCS

為了簡易起見,我們採用已訓練好的AlexNet model中的某個已編譯的graph檔,這當您在 ncappzoo 資料夾中執行 make 指令實就已經編譯好了。後續會有文章教您如何編譯一個已經訓練過的網路,但現在先來看看如何把graph載入NCS中。
# Read the graph file into a buffer
with open( GRAPH_PATH, mode='rb' ) as f:
blob = f.read()

# Load the graph buffer into the NCS
graph = device.AllocateGraph( blob )

Step 3:載入單一影像至Intel Movidius NCS並進行推論

Intel Movidius NCS是以Intel Movidius視覺處理元件(VPU)為基礎。這個元件對數百萬種監控攝影機、可用手勢控制的無人機、工業級機器視覺設備提供了視覺智能。如同VPU,NCS在系統中扮演的角色好比是個視覺上的共同處理器。以本範例來說,我們採用Ubuntu系統來讀取資料中的影像並 and offload it to the NCS for inference。NCS負責所有的神經網路運算,,這樣就可以節省CPU與記憶體來執行其它應用層的任務。
我們得先對影像進行處理(預處理)才能將影像載入NCS。
  1. 調整或裁切影像,好符合後續預訓練的網路規格。
    • GoogLeNet格式為224×224像素,AlexNet則是227×227像素
  2. 從整體資料集中,減去各個頻道 (Blue, Green and Red) 的均值。
    • 這在深度學習領域中是常見的 center the data 的技巧。
  3. 將影像轉為半精度浮點數 (fp16) 陣列,接著使用LoadTensor函式將影像載入NCS。
    • 搭配skimage函式庫只要一行程式碼就搞定
# Read & resize image [Image size is defined during training]
img = print_img = skimage.io.imread( IMAGES_PATH )
img = skimage.transform.resize( img, IMAGE_DIM, preserve_range=True )

# Convert RGB to BGR [skimage reads image in RGB, but Caffe uses BGR]
img = img[:, :, ::-1]

# Mean subtraction & scaling [A common technique used to center the data]
img = img.astype( numpy.float32 )
img = ( img - IMAGE_MEAN ) * IMAGE_STDDEV

# Load the image as a half-precision floating point array
graph.LoadTensor( img.astype( numpy.float16 ), 'user object' )

Step 4:讀取並顯示NCS的推論結果

根據您想要如何將推論結果整合入應用中,您可以選擇blocking or non-blocking 函式呼叫兩者之一來載入上述步驟中的tensor並讀取推論結果。現在我們使用預設的 blocking 呼叫 (無需使用特定的API).
# Get the results from NCS
output, userobj = graph.GetResult()

# Print the results
print('\n------- predictions --------')

labels = numpy.loadtxt( LABELS_FILE_PATH, str, delimiter = '\t' )

order = output.argsort()[::-1][:6]
for i in range( 0, 5 ):
print ('prediction ' + str(i) + ' is ' + labels[order[i]])

# Display the image on which inference was performed
skimage.io.imshow( IMAGES_PATH )
skimage.io.show( )

Step 5:卸載graph與關閉裝置

為了避免記憶體洩漏與/或區段錯誤(segmentation fault),請記得關閉任何開啟中的檔案、資源以及 deallocate 使用中的記憶體。
graph.DeallocateGraph()
device.CloseDevice()
恭喜!您的DNN 影像分類器完成了。

還可以試試

延伸閱讀

相關文章


留言

這個網誌中的熱門文章

opencv4nodejs Asynchronous OpenCV 3.x Binding for node.js   122     2715     414   0   0 Author Contributors Repository https://github.com/justadudewhohacks/opencv4nodejs Wiki Page https://github.com/justadudewhohacks/opencv4nodejs/wiki Last Commit Mar. 8, 2019 Created Aug. 20, 2017 opencv4nodejs           By its nature, JavaScript lacks the performance to implement Computer Vision tasks efficiently. Therefore this package brings the performance of the native OpenCV library to your Node.js application. This project targets OpenCV 3 and provides an asynchronous as well as an synchronous API. The ultimate goal of this project is to provide a comprehensive collection of Node.js bindings to the API of OpenCV and the OpenCV-contrib modules. An overview of available bindings can be found in the  API Documentation . Furthermore, contribution is highly appreciated....

2017通訊大賽「聯發科技物聯網開發競賽」決賽團隊29強出爐!作品都在11月24日頒獎典禮進行展示

2017通訊大賽「聯發科技物聯網開發競賽」決賽團隊29強出爐!作品都在11月24日頒獎典禮進行展示 LIS   發表於 2017年11月16日 10:31   收藏此文 2017通訊大賽「聯發科技物聯網開發競賽」決賽於11月4日在台北文創大樓舉行,共有29個隊伍進入決賽,角逐最後的大獎,並於11月24日進行頒獎,現場會有全部進入決賽團隊的展示攤位,總計約為100個,各種創意作品琳琅滿目,非常值得一看,這次錯過就要等一年。 「聯發科技物聯網開發競賽」決賽持續一整天,每個團隊都有15分鐘面對評審團做簡報與展示,並接受評審們的詢問。在所有團隊完成簡報與展示後,主辦單位便統計所有評審的分數,並由評審們進行審慎的討論,決定冠亞季軍及其他各獎項得主,結果將於11月24日的「2017通訊大賽頒獎典禮暨成果展」現場公佈並頒獎。 在「2017通訊大賽頒獎典禮暨成果展」現場,所有入圍決賽的團隊會設置攤位,總計約為100個,展示他們辛苦研發並實作的作品,無論是想觀摩別人的成品、了解物聯網應用有那些新的創意、尋找投資標的、尋找人才、尋求合作機會或是單純有興趣,都很適合花點時間到現場看看。 頒獎典禮暨成果展資訊如下: 日期:2017年11月24日(星期五) 地點:中油大樓國光廳(台北市信義區松仁路3號) 我要報名參加「2017通訊大賽頒獎典禮暨成果展」>>> 在參加「2017通訊大賽頒獎典禮暨成果展」之前,可以先在本文觀看各團隊的作品介紹。 決賽29強團隊如下: 長者安全救星 可隨意描繪或書寫之電子筆記系統 微觀天下 體適能訓練管理裝置 肌少症之行走速率檢測系統 Sugar Robot 賽亞人的飛機維修輔助器 iTemp你的溫度個人化管家 語音行動冰箱 MR模擬飛行 智慧防盜自行車 跨平台X-Y視覺馬達控制 Ironmet 菸消雲散 無人小艇 (Mini-USV) 救OK-緊急救援小幫手 穿戴式長照輔助系統 應用於教育之模組機器人教具 這味兒很台味 Aquarium Hub 發展遲緩兒童之擴增實境學習系統 蚊房四寶 車輛相控陣列聲納環境偵測系統 戶外團隊運動管理裝置 懷舊治療數位桌曆 SeeM智能眼罩 觸...
自製直播音源線 Bird Liang   October 6, 2016   in  View Bird Liang, Chief Engineer (梁子凌 / 技術長兼工程輔導長) 負責 AppWorks 技術策略與佈署,同時主導工程輔導。人生的第一份正職工作是創業,之後在外商圈電子業中闖蕩多年,經歷過 NXP、Sony、Newport Imagining、Crossmatch 等企業,從事無線通訊、影像系統、手機、面板、半導體、生物辨識等不同領域產品開發。熱愛學習新事物,協助團隊解決技術問題。放棄了幾近退休般的生活加入 AppWorks,為的是幫助更多在創業路上的人,並重新體驗創業的熱情。台大農機系、台科大電子所畢業,熱愛賞鳥、演奏管風琴,亦是不折不扣的熱血 Maker。 隨著 Facebook 開放一般帳號直播,現在我們只要拿起手機,隨時隨地都可以開始直播。回想幾年前 AppWorks 剛開始進行 Demo Day 直播時,還要將 HDMI 訊號接進 PC 中、再編碼打進 YouTube 的複雜度,實不可同日而語。 但用手機或平板直播最大的問題往往不是影像而是聲音。iPhone 或 iPad 上的攝影機,感度和解析度早已不輸數年前的專業攝影機,只要現場光不太差,大概都可以拍出令人滿意的畫面。但直播的聲音一直是個大問題,手機上的麥克風跟人耳所聽到的聲音其實有很大的差距,在比較大的場子裡,光是仰賴內建麥克風的收音多半無法有令人滿意的效果。 在大型的活動中,現場通常會有 PA 系統,最理想的方式還是想辦法將 PA 的訊號餵進 iPad 或 iPhone 中,保證聲音乾淨又清楚,絕對不會有其它有的沒的現場音。 iPhone 的耳機孔雖然可以插帶有麥克風的耳機 (如 Apple 原廠的 EarPods),但它的訊號位準是電容式麥克風的位準。PA 控台的輸出幾乎都是 line level 的,兩者的訊號電壓相差百倍以上,我們得做個小東西來解決這個差距。 Line 與 Mic 在 mixer 上,我們常會看到輸入可以在兩種規格中切換: line level 和 mic level。Mic level 顧名思義就是從麥克風來的訊號,這個訊號的規格是從不需供電的傳統動圈麥克風來的。因為不需...