20行代碼:Serverless架構下用Python輕鬆搞定圖像分類

圖像分類是人工智能領域的一個熱門話題,同樣在生產環境中也會經常會遇到類似的需求,那麼怎麼快速搭建一個圖像分類,或者圖像內容是別的API呢?

首先,給大家推薦一個圖像相關的庫:ImageAI

通過官方給的代碼,我們可以看到一個簡單的Demo:

<code>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)/<code>

通過這個Demo我們可以考慮將這個模塊部署到雲函數:

首先,我們在本地創建一個Python的項目:

mkdir imageDemo

然後新建文件:vim index.py

<code>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/<code>

創建完成之後,我們需要下載一下我們所依賴的模型:

<code>- 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,預測時間較慢,精度最高)/<code>

我們先用第一個SqueezeNet來做測試:

在官方文檔複製模型文件地址:

20行代碼:Serverless架構下用Python輕鬆搞定圖像分類

使用wget直接安裝:

<code>wget https://github.com/OlafenwaMoses/ImageAI/releases/download/1.0/squeezenet_weights_tf_dim_ordering_tf_kernels.h5/<code>
20行代碼:Serverless架構下用Python輕鬆搞定圖像分類

接下來,我們就需要進行安裝依賴了,這裡面貌似安裝的內容蠻多的:

20行代碼:Serverless架構下用Python輕鬆搞定圖像分類

而且這些依賴有一些需要編譯的,這就需要我們在centos + python2.7/3.6的版本下打包才可以,這樣就顯得非常複雜,尤其是mac/windows用戶,傷不起。

所以這時候,直接用我之前的打包網址:

20行代碼:Serverless架構下用Python輕鬆搞定圖像分類

20行代碼:Serverless架構下用Python輕鬆搞定圖像分類

直接下載解壓,然後放到自己的項目中:

20行代碼:Serverless架構下用Python輕鬆搞定圖像分類

最後,一步了,我們創建serverless.yaml

<code>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/<code>

完成之後,執行我們的sls --debug部署,部署過程中會有掃碼的登陸,登陸之後等待即可,完成之後,我們可以複製生成的URL:

20行代碼:Serverless架構下用Python輕鬆搞定圖像分類

通過Python語言進行測試,url就是我們剛才複製的+/image:

<code>import urllib.request
import base64

with open("1.jpg", 'rb') as f:
    base64_data = base64.b64encode(f.read())
    s = base64_data.decode()

url = '生成的地址/image'

print(urllib.request.urlopen(urllib.request.Request(
    url = url,
    data=s.encode("utf-8")
)).read().decode("utf-8"))/<code>

通過網絡搜索一張圖片,例如我找了這個:

20行代碼:Serverless架構下用Python輕鬆搞定圖像分類

得到運行結果:

<code>{"cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388}/<code>

將代碼修改一下,進行一下簡單的耗時測試:

<code>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 = '生成的地址/test'

    print(urllib.request.urlopen(urllib.request.Request(
        url = url,
        data=s.encode("utf-8")
    )).read().decode("utf-8"))
    print("cost: ", time.time() - start_time)/<code>

輸出結果:

<code>{"cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388}
cost:  2.1161561012268066
{"cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388}
cost:  1.1259253025054932
{"cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388}
cost:  1.3322770595550537
{"cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388}
cost:  1.3562259674072266
{"cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388}
cost:  1.0180821418762207
{"cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388}
cost:  1.4290671348571777
{"cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388}
cost:  1.5917718410491943
{"cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388}
cost:  1.1727900505065918
{"cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388}
cost:  2.962592840194702
{"cheetah": 83.12643766403198, "Irish_terrier": 2.315458096563816, "lion": 1.8476998433470726, "teddy": 1.6655176877975464, "baboon": 1.5562783926725388}
cost:  1.2248001098632812/<code>

這個數據,整體性能基本是在我可以接受的範圍內。

至此,我們通過Serveerless架構搭建的Python版本的圖像識別/分類小工具做好了。


20行代碼:Serverless架構下用Python輕鬆搞定圖像分類


分享到:


相關文章: