(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小時 |
難度 | ★★★★★ |
材料表 |
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) 並執行
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 中一些需要調整的使用者參數::
- GRAPH_PATH:要進行推論的graph檔路徑
- 預設值為 ~/workspace/ncappzoo/caffe/GoogLeNet/graph
- IMAGE_PATH:想要分類的影像路徑
- 預設值為 ~/workspace/ncappzoo/data/images/cat.jpg
- IMAGE_DIM:所採用神經網路之影像尺寸規格
- 例如 GoogLeNet 採用 224×224像素,AlexNet則是227×227像素
- IMAGE_STDDEV:您選用之神經網路所定義的標準差(scaling value)
- 例如:GoogLeNet不採用任何比例因子,但InceptionV3的比例因子為128 (stddev = 1/128)
- IMAGE_MEAN:均值減法(Mean subtraction)是深度學習領域中常用的資料整理技巧。
- 對ILSVRC資料集來說,B、G、R的平均值分別為102、117與123
請先由mvnc函式庫匯入mvncapi模組,才能順利使用NCSDK API framework。
Step 1:開啟enumerated裝置
如同其他USB裝置,當您將NCS接上應用程式處理器 (執行Ubuntu的桌上型/筆記型電腦) 的USB埠,前者會被後者枚舉為一個USB裝置。我們可以呼叫API來檢視各個NCS裝置。
您知道在同一個應用程式中,可以連接多個NCS神經運算棒來提高推論效能嗎?以下語法是運用API 呼叫單一NCS並開啟 (意即準備好操作).
Step 2:將graph檔載入NCS
為了簡易起見,我們採用已訓練好的AlexNet model中的某個已編譯的graph檔,這當您在 ncappzoo 資料夾中執行 make 指令實就已經編譯好了。後續會有文章教您如何編譯一個已經訓練過的網路,但現在先來看看如何把graph載入NCS中。
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。
- 調整或裁切影像,好符合後續預訓練的網路規格。
- GoogLeNet格式為224×224像素,AlexNet則是227×227像素
- 從整體資料集中,減去各個頻道 (Blue, Green and Red) 的均值。
- 這在深度學習領域中是常見的 center the data 的技巧。
- 將影像轉為半精度浮點數 (fp16) 陣列,接著使用LoadTensor函式將影像載入NCS。
- 搭配skimage函式庫只要一行程式碼就搞定
Step 4:讀取並顯示NCS的推論結果
根據您想要如何將推論結果整合入應用中,您可以選擇blocking or non-blocking 函式呼叫兩者之一來載入上述步驟中的tensor並讀取推論結果。現在我們使用預設的 blocking 呼叫 (無需使用特定的API).
Step 5:卸載graph與關閉裝置
為了避免記憶體洩漏與/或區段錯誤(segmentation fault),請記得關閉任何開啟中的檔案、資源以及 deallocate 使用中的記憶體。
恭喜!您的DNN 影像分類器完成了。
還可以試試
- 本範例只能讀取一張影像,試著修改程式讓它可以從同一個資料夾中讀取並推論多張影像。
- 使用OpenCV並透過圖形化視窗來顯示影像(一或多張)與推論結果。
- 在RPI3或MinnowBoard這類的單板電腦上執行本專案,可參考[在Raspberry Pi 上執行 Intel® Movidius™ NCS應用程式] 一文
延伸閱讀
- 認識Intel Movidius NCS的開發流程
- 讀一下這篇關於神經網路設定的文章,介紹了均值減法與scaling
相關文章
- 使用 Intel® Movidius™ Neural Compute Stick搭配Raspberry Pi 3執行MobileNets
- 在Raspberry Pi 上執行 Intel® Movidius™ NCS應用程式