【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小時
難度  ★★★★★
材料表

 

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) 並執行

[pastacode lang=”bash” manual=”mkdir%20-p%20~%2Fworkspace%0Acd%20~%2Fworkspace%0Agit%20clone%20https%3A%2F%2Fgithub.com%2Fmovidius%2Fncappzoo%0Acd%20ncappzoo%2Fapps%2Fimage-classifier%0Amake%20run” message=”” highlight=”” provider=”manual”/]

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。

[pastacode lang=”python” manual=”import%20mvnc.mvncapi%20as%20mvnc” message=”” highlight=”” provider=”manual”/]

 

Step 1:開啟enumerated裝置

如同其他USB裝置,當您將NCS接上應用程式處理器 (執行Ubuntu的桌上型/筆記型電腦) 的USB埠,前者會被後者枚舉為一個USB裝置。我們可以呼叫API來檢視各個NCS裝置。

[pastacode lang=”python” manual=”%23%20Look%20for%20enumerated%20Intel%20Movidius%20NCS%20device(s)%3B%20quit%20program%20if%20none%20found.%0Adevices%20%3D%20mvnc.EnumerateDevices()%0Aif%20len(%20devices%20)%20%3D%3D%200%3A%0Aprint(%20’No%20devices%20found’%20)%0Aquit()” message=”” highlight=”” provider=”manual”/]

您知道在同一個應用程式中,可以連接多個NCS神經運算棒來提高推論效能嗎?以下語法是運用API 呼叫單一NCS並開啟 (意即準備好操作).

[pastacode lang=”python” manual=”%23%20Get%20a%20handle%20to%20the%20first%20enumerated%20device%20and%20open%20it%0Adevice%20%3D%20mvnc.Device(%20devices%5B0%5D%20)%0Adevice.OpenDevice()” message=”” highlight=”” provider=”manual”/]

 

Step 2:將graph檔載入NCS

為了簡易起見,我們採用已訓練好的AlexNet model中的某個已編譯的graph檔,這當您在 ncappzoo 資料夾中執行 make 指令實就已經編譯好了。後續會有文章教您如何編譯一個已經訓練過的網路,但現在先來看看如何把graph載入NCS中。

[pastacode lang=”python” manual=”%23%20Read%20the%20graph%20file%20into%20a%20buffer%0Awith%20open(%20GRAPH_PATH%2C%20mode%3D’rb’%20)%20as%20f%3A%0Ablob%20%3D%20f.read()%0A%0A%23%20Load%20the%20graph%20buffer%20into%20the%20NCS%0Agraph%20%3D%20device.AllocateGraph(%20blob%20)%0A%0A” message=”” highlight=”” provider=”manual”/]

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函式庫只要一行程式碼就搞定
[pastacode lang=”python” manual=”%23%20Read%20%26%20resize%20image%20%5BImage%20size%20is%20defined%20during%20training%5D%0Aimg%20%3D%20print_img%20%3D%20skimage.io.imread(%20IMAGES_PATH%20)%0Aimg%20%3D%20skimage.transform.resize(%20img%2C%20IMAGE_DIM%2C%20preserve_range%3DTrue%20)%0A%0A%23%20Convert%20RGB%20to%20BGR%20%5Bskimage%20reads%20image%20in%20RGB%2C%20but%20Caffe%20uses%20BGR%5D%0Aimg%20%3D%20img%5B%3A%2C%20%3A%2C%20%3A%3A-1%5D%0A%0A%23%20Mean%20subtraction%20%26%20scaling%20%5BA%20common%20technique%20used%20to%20center%20the%20data%5D%0Aimg%20%3D%20img.astype(%20numpy.float32%20)%0Aimg%20%3D%20(%20img%20-%20IMAGE_MEAN%20)%20*%20IMAGE_STDDEV%0A%0A%23%20Load%20the%20image%20as%20a%20half-precision%20floating%20point%20array%0Agraph.LoadTensor(%20img.astype(%20numpy.float16%20)%2C%20’user%20object’%20)” message=”” highlight=”” provider=”manual”/]

 

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

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

[pastacode lang=”python” manual=”%23%20Get%20the%20results%20from%20NCS%0Aoutput%2C%20userobj%20%3D%20graph.GetResult()%0A%0A%23%20Print%20the%20results%0Aprint(‘%5Cn——-%20predictions%20——–‘)%0A%0Alabels%20%3D%20numpy.loadtxt(%20LABELS_FILE_PATH%2C%20str%2C%20delimiter%20%3D%20’%5Ct’%20)%0A%0Aorder%20%3D%20output.argsort()%5B%3A%3A-1%5D%5B%3A6%5D%0Afor%20i%20in%20range(%200%2C%205%20)%3A%0Aprint%20(‘prediction%20’%20%2B%20str(i)%20%2B%20’%20is%20’%20%2B%20labels%5Border%5Bi%5D%5D)%0A%0A%23%20Display%20the%20image%20on%20which%20inference%20was%20performed%0Askimage.io.imshow(%20IMAGES_PATH%20)%0Askimage.io.show(%20)” message=”” highlight=”” provider=”manual”/]

 

Step 5:卸載graph與關閉裝置

為了避免記憶體洩漏與/或區段錯誤(segmentation fault),請記得關閉任何開啟中的檔案、資源以及 deallocate 使用中的記憶體。

[pastacode lang=”python” manual=”graph.DeallocateGraph()%0Adevice.CloseDevice()” message=”” highlight=”” provider=”manual”/]

恭喜!您的DNN 影像分類器完成了。

 

還可以試試

延伸閱讀

相關文章

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *