"與其停留在概念理論層面,不如動手去實現一個簡單demo 。" ——魯迅
前言
目前提供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。
計划下一篇介紹基於圖片識別的視頻自動分類,比如自動鑒黃等軟件。