圖像分類是人工智能領域的一個熱門話題,通俗來說,就是根據各自在圖像信息中反映的不一樣特徵,把不一樣類別的目標區分開。圖像分類利用計算機對圖像進行定量分析,把圖像或圖像中的每一個像元或區域劃歸爲若干個類別中的某一種,代替人的視覺判讀。html
在實際生活中,咱們也會遇到圖像分類的應用場景,例如咱們經常使用的經過拍照花朵來識別花朵信息,經過人臉匹對人物信息等。一般,圖像識別或分類工具都是在客戶端進行數據採集,在服務端進行運算得到結果。所以,通常都會有專門的 API 來實現圖像識別,雲廠商也會有償提供相似的能力:python
本文將嘗試經過一個有趣的 Python 庫,快速將圖像分類的功能搭建在雲函數上,而且和 API 網關結合,對外提供 API 功能,實現一個 Serverless 架構的 " 圖像分類 API"。git
首先,咱們須要一個依賴庫:ImageAI
。github
什麼是 ImageAI 呢?其官方文檔是這樣描述的:算法
ImageAI 是一個 python 庫,旨在使開發人員可以使用簡單的幾行代碼構建具備包含深度學習和計算機視覺功能的應用程序和系統。
ImageAI 本着簡潔的原則,支持最早進的機器學習算法,用於圖像預測、自定義圖像預測、物體檢測、視頻檢測、視頻對象跟蹤和圖像預測訓練。ImageAI 目前支持使用在 ImageNet-1000 數據集上訓練的 4 種不一樣機器學習算法進行圖像預測和訓練。ImageAI 還支持使用在 COCO 數據集上訓練的 RetinaNet 進行對象檢測、視頻檢測和對象跟蹤。 最終,ImageAI 將爲計算機視覺提供更普遍和更專業化的支持,包括但不限於特殊環境和特殊領域的圖像識別。express
簡單理解,就是 ImageAI 依賴庫能夠幫助用戶完成基本的圖像識別和視頻的目標提取。不過,ImageAI 雖然提供一些數據集和模型,但咱們也能夠根據自身須要對其進行額外的訓練,進行定製化拓展。json
其官方代碼給出了這樣一個簡單的 Demo:vim
from imageai.Prediction import ImagePrediction import os execution_path = os.getcwd() prediction = ImagePrediction() prediction.setModelTypeAsResNet() prediction.setModelPath(os.path.join(execution_path, "resnet50_weights_tf_dim_ordering_tf_kernels.h5")) prediction.loadModel() predictions, probabilities = prediction.predictImage(os.path.join(execution_path, "1.jpg"), result_count=5 ) for eachPrediction, eachProbability in zip(predictions, probabilities): print(eachPrediction + " : " + eachProbability)
咱們能夠在本地進行初步運行,指定圖片1.jpg
爲下圖時:api
能夠獲得結果:瀏覽器
convertible : 52.459537982940674 sports_car : 37.61286735534668 pickup : 3.175118938088417 car_wheel : 1.8175017088651657 minivan : 1.7487028613686562
經過上面的 Demo,咱們能夠考慮將這個模塊部署到雲函數:
mkdir imageDemo
vim index.py
{"picture": 圖片的 base64}
,出參定爲:{"prediction": 圖片分類的結果}
實現的代碼以下:
from imageai.Prediction import ImagePrediction import os, base64, random execution_path = os.getcwd() prediction = ImagePrediction() prediction.setModelTypeAsSqueezeNet() prediction.setModelPath(os.path.join(execution_path, "squeezenet_weights_tf_dim_ordering_tf_kernels.h5")) prediction.loadModel() def main_handler(event, context): imgData = base64.b64decode(event["body"]) fileName = '/tmp/' + "".join(random.sample('zyxwvutsrqponmlkjihgfedcba', 5)) with open(fileName, 'wb') as f: f.write(imgData) resultData = {} predictions, probabilities = prediction.predictImage(fileName, result_count=5) for eachPrediction, eachProbability in zip(predictions, probabilities): resultData[eachPrediction] = eachProbability return resultData
建立完成以後,下載所依賴的模型:
由於咱們僅用於測試,因此選擇一個比較小的模型就能夠:SqueezeNet
:
在官方文檔複製模型文件地址:
使用wget
直接安裝:
wget https://github.com/OlafenwaMoses/ImageAI/releases/download/1.0/squeezenet_weights_tf_dim_ordering_tf_kernels.h5
接下來,進行依賴安裝:
因爲騰訊雲 Serveless 產品,在 Python Runtime 中還不支持在線安裝依賴,因此須要手動打包依賴,而且上傳。在 Python 的各類依賴庫中,有不少依賴可能有編譯生成二進制文件的過程,這就會致使不一樣環境下打包的依賴沒法通用。
因此,最好的方法就是經過對應的操做系統 + 語言版本進行打包。咱們就是在 CentOS+Python3.6 的環境下進行依賴打包。
對於不少 MacOS 用戶和 Windows 用戶來講,這確實不是一個很友好的過程,因此爲了方便你們使用,我在 Serverless 架構上作了一個在線打包依賴的工具,因此能夠直接用該工具進行打包:
生成壓縮包以後,直接下載解壓,而且放到本身的項目中便可:
最後一步,建立serverless.yaml
imageDemo: component: "@serverless/tencent-scf" inputs: name: imageDemo codeUri: ./ handler: index.main_handler runtime: Python3.6 region: ap-guangzhou description: 圖像識別 / 分類 Demo memorySize: 256 timeout: 10 events: - apigw: name: imageDemo_apigw_service parameters: protocols: - http serviceName: serverless description: 圖像識別 / 分類 DemoAPI environment: release endpoints: - path: /image method: ANY
完成以後,執行sls --debug
部署,部署過程當中會有掃碼登錄,登錄以後等待便可,完成以後,就能夠看到部署地址。
經過 Python 語言進行測試,接口地址就是剛纔複製的 +/image
,例如:
import json import urllib.request import base64 with open("1.jpg", 'rb') as f: base64_data = base64.b64encode(f.read()) s = base64_data.decode() url = 'http://service-9p7hbgvg-1256773370.gz.apigw.tencentcs.com/release/image' print(urllib.request.urlopen(urllib.request.Request( url = url, data= json.dumps({'picture': s}).encode("utf-8") )).read().decode("utf-8"))
經過網絡搜索一張圖片:
獲得運行結果:
{ "prediction": { "cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388 } }
經過這個結果,咱們能夠看到圖片的基礎分類 / 預測已經成功了,爲了證實這個接口的時延狀況,能夠對程序進行基本改造:
import urllib.request import base64, time for i in range(0,10): start_time = time.time() with open("1.jpg", 'rb') as f: base64_data = base64.b64encode(f.read()) s = base64_data.decode() url = 'http://service-9p7hbgvg-1256773370.gz.apigw.tencentcs.com/release/image' print(urllib.request.urlopen(urllib.request.Request( url = url, data= json.dumps({'picture': s}).encode("utf-8") )).read().decode("utf-8")) print("cost: ", time.time() - start_time)
輸出結果:
{"prediction":{"cheetah":83.12643766403198,"Irish_terrier":2.315458096563816,"lion":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.5562783926725388}} cost: 2.1161561012268066 {"prediction":{"cheetah":83.12643766403198,"Irish_terrier":2.315458096563816,"lion":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.5562783926725388}} cost: 1.1259253025054932 {"prediction":{"cheetah":83.12643766403198,"Irish_terrier":2.315458096563816,"lion":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.5562783926725388}} cost: 1.3322770595550537 {"prediction":{"cheetah":83.12643766403198,"Irish_terrier":2.315458096563816,"lion":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.5562783926725388}} cost: 1.3562259674072266 {"prediction":{"cheetah":83.12643766403198,"Irish_terrier":2.315458096563816,"lion":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.5562783926725388}} cost: 1.0180821418762207 {"prediction":{"cheetah":83.12643766403198,"Irish_terrier":2.315458096563816,"lion":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.5562783926725388}} cost: 1.4290671348571777 {"prediction":{"cheetah":83.12643766403198,"Irish_terrier":2.315458096563816,"lion":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.5562783926725388}} cost: 1.5917718410491943 {"prediction":{"cheetah":83.12643766403198,"Irish_terrier":2.315458096563816,"lion":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.5562783926725388}} cost: 1.1727900505065918 {"prediction":{"cheetah":83.12643766403198,"Irish_terrier":2.315458096563816,"lion":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.5562783926725388}} cost: 2.962592840194702 {"prediction":{"cheetah":83.12643766403198,"Irish_terrier":2.315458096563816,"lion":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.5562783926725388}} cost: 1.2248001098632812
經過上面一組數據,咱們能夠看到總體的耗時基本控制在 1-1.5 秒之間。
固然,若是想要對接口性能進行更多的測試,例如經過併發測試來看併發狀況下接口性能表現等。
至此,咱們經過 Serveerless 架構搭建的 Python 版本的圖像識別 / 分類小工具作好了。
Serverless 架構下進行人工智能相關的應用能夠是說是很是多的,本文是經過一個已有的依賴庫,實現一個圖像分類 / 預測的接口。imageAI
這個依賴庫相對來講自由度比較高,能夠根據自身須要用來定製化本身的模型。本文算是拋磚引玉,期待更多人經過 Serverless 架構部署本身的"人工智能" API。
咱們誠邀您來體驗最便捷的 Serverless 開發和部署方式。在試用期內,相關聯的產品及服務均提供免費資源和專業的技術支持,幫助您的業務快速、便捷地實現 Serverless!
3 秒你能作什麼?喝一口水,看一封郵件,仍是 —— 部署一個完整的 Serverless 應用?
複製連接至 PC 瀏覽器訪問:https://serverless.cloud.tencent.com/deploy/express
3 秒極速部署,當即體驗史上最快的 Serverless HTTP 實戰開發!
傳送門:
- GitHub: github.com/serverless
- 官網:serverless.com
歡迎訪問:Serverless 中文網,您能夠在 最佳實踐 裏體驗更多關於 Serverless 應用的開發!