影像分類是人工智能領域的一個熱門話題,通俗來講,就是根據各自在影像資訊中反映的不同特征,把不同類別的目標區分開,影像分類利用計算機對影像進行定量分析,把影像或影像中的每個像元或區域劃歸為若干個類別中的某一種,代替人的視覺判讀,
在實際生活中,我們也會遇到影像分類的應用場景,例如我們常用的通過拍斬訓朵來識別花朵資訊,通過人臉匹對人物資訊等,通常,影像識別或分類工具都是在客戶端進行資料采集,在服務端進行運算獲得結果,因此,一般都會有專門的 API 來實作影像識別,云廠商也會有償提供類似的能力:
- 華為云影像標簽

- 騰訊云影像分析

本文將嘗試通過一個有趣的 Python 庫,快速將影像分類的功能搭建在云函式上,并且和 API 網關結合,對外提供 API 功能,實作一個 Serverless 架構的 " 影像分類 API",
入門 ImageAI
首先,我們需要一個依賴庫:ImageAI,
什么是 ImageAI 呢?其官方檔案是這樣描述的:
ImageAI 是一個 python 庫,旨在使開發人員能夠使用簡單的幾行代碼構建具有包含深度學習和計算機視覺功能的應用程式和系統,
ImageAI 本著簡潔的原則,支持最先進的機器學習演算法,用于影像預測、自定義影像預測、物體檢測、視頻檢測、視頻物件跟蹤和影像預測訓練,ImageAI 目前支持使用在 ImageNet-1000 資料集上訓練的 4 種不同機器學習演算法進行影像預測和訓練,ImageAI 還支持使用在 COCO 資料集上訓練的 RetinaNet 進行物件檢測、視頻檢測和物件跟蹤, 最終,ImageAI 將為計算機視覺提供更廣泛和更專業化的支持,包括但不限于特殊環境和特殊領域的影像識別,
簡單理解,就是 ImageAI 依賴庫可以幫助用戶完成基本的影像識別和視頻的目標提取,不過,ImageAI 雖然提供一些資料集和模型,但我們也可以根據自身需要對其進行額外的訓練,進行定制化拓展,
其官方代碼給出了這樣一個簡單的 Demo:
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為下圖時:

可以得到結果:
convertible : 52.459537982940674
sports_car : 37.61286735534668
pickup : 3.175118938088417
car_wheel : 1.8175017088651657
minivan : 1.7487028613686562
讓 ImageAI 上云(部署到 Serverless 架構上)
通過上面的 Demo,我們可以考慮將這個模塊部署到云函式:
- 首先,在本地創建一個 Python 的專案:
mkdir imageDemo - 新建檔案:
vim index.py - 根據云函式的一些特殊形式,我們對 Demo 進行部分改造
- 將初始化的代碼放在外層;
- 將預測部分當做觸發所需要執行的部分,放在入口方法中(此處是 main_handler);
- 云函式與 API 網關結合對二進制檔案支持并不是十分的友善,所以此處通過 base64 進行圖片傳輸;
- 入參定為
{"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 = https://www.cnblogs.com/serverlesscloud/p/base64.b64decode(event["body"])
fileName = '/tmp/' + "".join(random.sample('zyxwvutsrqponmlkjihgfedcba', 5))
with open(fileName, 'wb') as f:
f.write(imgData)
resultData = https://www.cnblogs.com/serverlesscloud/p/{}
predictions, probabilities = prediction.predictImage(fileName, result_count=5)
for eachPrediction, eachProbability in zip(predictions, probabilities):
resultData[eachPrediction] = eachProbability
return resultData
創建完成之后,下載所依賴的模型:
- SqueezeNet(檔案大小:4.82 MB,預測時間最短,精準度適中)
- ResNet50 by Microsoft Research (檔案大小:98 MB,預測時間較快,精準度高)
- InceptionV3 by Google Brain team (檔案大小:91.6 MB,預測時間慢,精度更高)
- DenseNet121 by Facebook AI Research (檔案大小:31.6 MB,預測時間較慢,精度最高)
因為我們僅用于測驗,所以選擇一個比較小的模型就可以: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 = https://www.cnblogs.com/serverlesscloud/p/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= https://www.cnblogs.com/serverlesscloud/p/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 = https://www.cnblogs.com/serverlesscloud/p/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= https://www.cnblogs.com/serverlesscloud/p/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 Framework 試用計劃
我們誠邀您來體驗最便捷的 Serverless 開發和部署方式,在試用期內,相關聯的產品及服務均提供免費資源和專業的技術支持,幫助您的業務快速、便捷地實作 Serverless!
One More Thing
3 秒你能做什么?喝一口水,看一封郵件,還是 —— 部署一個完整的 Serverless 應用?
復制鏈接至 PC 瀏覽器訪問:https://serverless.cloud.tencent.com/deploy/express
3 秒極速部署,立即體驗史上最快的 Serverless HTTP 實戰開發!
傳送門:
- GitHub: github.com/serverless
- 官網:serverless.com
歡迎訪問:Serverless 中文網,您可以在 最佳實踐 里體驗更多關于 Serverless 應用的開發!
推薦閱讀:《Serverless 架構:從原理、設計到專案實戰》
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/18043.html
標籤:其他
