[AI開發]Python+Tensorflow打造自己的計算機視覺API服務

周見智發表於2018-07-06

"與其停留在概念理論層面,不如動手去實現一個簡單demo 。"       ——魯迅

沒有原始碼都是耍流氓github

前言

目前提供AI開發相關API介面的公司有很多,國外如微軟、谷歌,國內的百度、騰訊等都有開放API介面。開發者只需要呼叫相關介面,幾步就能開發出一個“智慧APP”。通常情況AI介面有以下幾類:

  • 計算機視覺

      影象分類、影象目標檢測以及視訊檢測跟蹤等等。這類API主要用於處理影象和視訊,能夠給影象打tag,並分析視訊圖片中的物體及其對應座標軌跡等。

  • 語言

      包括自然語言處理,分析自然語言含義,評估情緒等,例如機器翻譯等。

  • 語音

      將語言音訊轉換為文字,使用聲音進行驗證,或嚮應用新增說話人識別。 

  • 知識

      通過對映覆雜資訊和資料來解決任務,例如智慧建議和語義搜尋。

基於Web Service的智慧API介面讓我們不需要了解複雜的機器學習以及數學知識就能輕鬆開發出智慧APP。但是,本文將介紹如何完全自己動手去實現一個智慧API介面服務,由於涉及到的東西非常多,本文僅以我比較熟悉的“計算機視覺”為例,包含“影象分類(image classification)”和“目標檢測(target detect)”,之後如果有機會,我會介紹“視訊軌跡跟蹤”相關的東西,大概就是影象處理的升級版。在開始正文之前,先解釋幾個名詞。AI的概念近一兩年尤其火熱,“機器學習”以及“深度學習”的技術介紹到處都是,這裡再簡單介紹一下我對它們的理解:

人工智慧:

又名AI,概念出現得特別早,上世紀五六十年代就有。人工智慧大概可以分為兩大類,一類“強人工智慧”,你可以理解為完全具備跟人類一樣的思維和意識的計算機程式;第二類“弱人工智慧”,大概就是指計算機能夠完成大部分相對較高階的行為,比如前面提到的理解圖片含義,理解語言含義以及理解語音等等。我們日常提到的人工智慧通常指第二類,常見的有計算機視覺、語音識別、機器翻譯、推薦系統、搜尋引擎甚至一些智慧美圖的APP,這些都可以說使用了人工智慧技術,因為它們內部都使用了相關機器學習或者深度學習的演算法。

機器學習:

這個概念也出現得很早,大概上世界八九十年代(?)。以前的概念中,計算機必須按照人編寫的程式去執行任務,對於程式中沒有的邏輯,計算機是不可能去做的。機器學習出現後,計算機具備人類“掌握經驗”的能力,在通過大量學習/總結規律之後,計算機能夠預測它之前並沒有見過的事物。

深度學習:

深度學習的概念近幾年才出現,你可以理解為它是機器學習的升級。之所以近幾年突然流行,是因為一些傳統機器學習演算法(比如神經網路)要想取得非常好的效能,神經網路必須足夠複雜,同時需要大量的學習資料,這時計算能力遇到了瓶頸。而近幾年隨著硬體效能普遍提升,再加上網際網路時代爆炸式的資料儲存,訓練出足夠複雜的模型已經不再是遙不可及。因此,可以將深度學習理解為更復雜的機器學習方式。

好了,基本概念理清楚之後,開始進入正題了。這次我需要實現計算機視覺中的兩大智慧API介面:圖片分類和目標檢測。

 

技術和開發環境

下面是用到的技術和環境:

1)Python 3.5.2 (PIL、numpy、opencv、matplotlib等一些常見的庫)

2)Tensorflow 1.8.0(GPU版本)

3)Keras 2.2.0 (backend是tensorflow)

4)Yolo v3(目標檢測演算法)

5)Windows 10 + Navida GTX 1080 顯示卡(需要安裝cuda 和 cudnn)

6)VS Code 1.19.3

關於以上技術的介紹以及初次使用時的安裝步驟,我這裡不再多說了,網上教程很多,提示一下,初次安裝環境,會有很多坑。一定要使用gpu版本的tensorflow,如果僅僅是自己搞著練練手,熟悉熟悉流程,安裝cpu版本也行。

 

介面定義

好了,技術環境介紹完了之後,再把介面確定下來:

名稱

介面

引數

返回

線上圖片檢測

/detect/online

Method=POST

online_image_url=url[string]

{

  “image”:”result_url”,

  “results”:[

  {

       “box”:[left, top, right, bottom],

       “score”:score,

       “class”:class

  },

  {

       “box”:[left, top, right, bottom],

       “score”:score,

       “class”:class

  }

  ...

  ],

  “time”:create_time,

  “type”:”online”

}

本地圖片檢測

/detect/local

Method=POST

local_image=file data[byte]

 

multipart/form-data

{

  “image”:”result_url”,

  “results”:[

  {

       “box”:[left, top, right, bottom],

       “score”:score,

       “class”:class

  },

  {

       “box”:[left, top, right, bottom],

       “score”:score,

       “class”:class

  }

  ...

  ],

  “time”:create_time,

  “type”:”local”

}

線上圖片分類

/classification/online

Method=POST

online_image_url=url[string]

還沒完成

本地圖片分類

/classification/local

Method=POST

local_image=file_data[byte]

 

multipart/form_data

還沒完成

 

寫這篇部落格的時候,圖片分類的模型還沒有訓練好,所以暫時放一下,下次更新。以上四個介面分兩類,一類是提交線上圖片的url即可,二類是提交本地圖片檔案(表單上傳)。兩類都需要POST方式提交,返回結果是json格式,裡面包含了處理之後的圖片url(所有的結果已經繪製在上面了),還有處理的raw_data,客戶端收到這些raw_data後可以自己用作其他地方。

 

目標檢測

目標檢測演算法使用的是YOLO V3,這裡是C語言實現的版本:http://pjreddie.com/darknet/ 。由於我比較熟悉Python,所以我用的是另外一個Python版本的實現(基於Keras),這裡是Keras版本的實現:https://github.com/qqwweee/keras-yolo3。 如果想要訓練更好的模型,需要自己準備資料集,原始碼中有一個我寫的開源工具,專門用來標記這個框架所用的資料集(這個工具需要.net 4.0+)。

訓練資料集使用的是微軟的COCO資料集(https://github.com/cocodataset/cocoapi),這個也是C語言版本的預設資料集,你可以直接從官網上下載訓練好的模型使用。

 

圖片分類

待更新...

 

Web伺服器

由於是Web API,那麼你首先必須得有一個自己的Web Server。因為這是一個demo程式,所以沒必要使用類似Django 、Flask這樣的框架,於是索性就自己寫一個吧。功能很簡單,提供靜態檔案訪問、以及可以處理我的API介面就行,寫完核心程式碼大約200行(包含API介面處理的邏輯)。整個Web程式用到的模組大概有:http.server、PIL、urllib、io、uuid、time、json、os以及cgi。可以看到並不複雜。

整個Web Server的程式碼:

 

處理邏輯

從呼叫API介面到返回處理結果的流程相當簡單,跟普通的HTTP請求一樣,客戶端傳送HTTP請求,攜帶物件引數,Web Server在接收到資料後,開始呼叫計算模組,並將計算結果轉換成json格式返回給客戶端:

圖中橙色部分為關鍵部分,詳細實現請參見原始碼中的vision模組。

 

Demo效果

Demo中寫好了一個靜態html頁面,執行python server.py後,在瀏覽中訪問:http://localhost:8080/web-app/index.html即可看見測試頁面。左邊為處理之後的圖片,右邊為返回的json結果。

檢測線上圖片,在文字框中copy圖片url,點選提交。

上傳本地圖片,點選提交。

與此同時,在控制檯(或我自己的VS Code整合終端)中可以看到如下輸出:

最開始是檢測花費的時間,接著就是檢測到的目標物體以及對應的座標、分數等等。後面是轉換之後的json字串,最後客戶端根據json中的url載入處理之後的圖片。

視訊目標跟蹤

這裡稍微說一下跟視訊有關的處理。對於視訊來講,它跟圖片一樣,由一張張圖片組成,唯一的區別就是它具備時間的維度。我們不僅要檢測每幀中的目標,還要判斷前後幀之間各個目標之間的聯絡。然後利用目標物體的位移差來分析物體行為,對於路上車輛來講,可以分析“異常停車”、“壓線”、“逆行掉頭”、“車速”、“流量統計”、“拋灑物”等資料。

 

關於機器學習

AI開發離不開機器學習(深度學習),而機器學習涉及到的知識相對來講非常廣泛,不僅僅要求開發者掌握好程式設計技能,還對數學知識有較高的要求。

我認為作為普通程式設計師,如果要學習AI開發,請用一種Top Down的方式,拋開晦澀難懂的數學理論,先找個適合自己的機器學習框架(比如tensorflow或者基於它的keras),學會如何準備訓練資料集(比如本文中如何去標記圖片?),如何訓練自己的模型,然後用訓練得到的模型去解決一些小問題(比如本文中的影象目標檢測)。等自己對機器學習有一種具體的認識之後,經過一段時間的摸索,會自然而然地引導我們去了解底層的數學原理,這個時候再去搞清楚這些原理是什麼。

個人認為,不要先上來就要搞懂什麼是梯度下降優化法、什麼是目標函式、什麼是啟用函式,什麼是學習率...,這些概念確實需要掌握,但是不是你學習機器學習最開始的時候。另外學習機器學習,請使用Python。

 

計劃下一篇介紹基於圖片識別的視訊自動分類,比如自動鑑黃等軟體。

 

相關文章