Bootstrap

Serverless架构下Tensorflow与目标检测系统

ImageAI是一个Python库,旨在使开发人员能够使用简单的几行代码构建具有包含深度学习和计算机视觉功能的应用程序和系统。ImageAI本着简洁的原则,支持最先进的机器学习算法,用于图像预测,自定义图像预测,物体检测,视频检测,视频对象跟踪和图像预测训练。该库目前支持使用在ImageNet-1000数据集上训练的4种不同机器学习算法进行图像预测和训练,除此之外还支持使用在COCO数据集上训练的RetinaNet进行对象检测,视频检测和对象跟踪等。

ImageAI项目是一个依赖Tensorflow 1.4.0(及更高版本)的项目,通过对Tesorflow项目的进一步封装,ImageAI项目提供用于图像预测的4种算法包括 SqueezeNetResNetInceptionV3DenseNet,可以通过非常简单的方法实现图像预测、目标检测等任务。

本地开发

首先明确要进行目标检测的图像:

然后可以根据ImageAI提供的开发文档,实现以下代码:

# index.py
from imageai.Prediction import ImagePrediction

# 模型加载
prediction = ImagePrediction()
prediction.setModelTypeAsResNet()
prediction.setModelPath("resnet50_weights_tf_dim_ordering_tf_kernels.h5")
prediction.loadModel()

predictions, probabilities = prediction.predictImage("./picture.jpg", result_count=5 )
for eachPrediction, eachProbability in zip(predictions, probabilities):
    print(str(eachPrediction) + " : " + str(eachProbability))

完成代码开发之后,可以通过执行该文件进行效果测试:

python index.py

可以得到结果:

laptop : 71.43893241882324
notebook : 16.265612840652466
modem : 4.899394512176514
hard_disc : 4.007557779550552
mouse : 1.2981942854821682

如果在使用过程中觉得模型resnet50_weights_tf_dim_ordering_tf_kernels.h5过大,耗时过长,可以按需求选择模型:

  • 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,预测时间较慢,精度最高)

部署到Serverless架构

部署前准备

在本地完成ImageAI的基本测试运行之后,可以将项目部署到Serverless架构上。在Serverless架构上,该项目的运行流程基本是:

所以这里涉及到几个部分:

  • 获取本地上传的图片

  • 图片缓存到/tmp/目录下

  • 通过AI进行预测

  • 返回数据

按照以上流程,以阿里云函数计算和轻量级Python Web框架Bottle为例,可以分别实现页面代码以及逻辑代码。其中逻辑代码主要是将上文在本地开发的案例进行稍作修改,与Bottle框架进行结合:

# -*- coding: utf-8 -*-
from imageai.Prediction import ImagePrediction
import base64
import bottle
import random
import json

# 随机字符串
randomStr = lambda num=5: "".join(random.sample('abcdefghijklmnopqrstuvwxyz', num))

# 模型加载
prediction = ImagePrediction()
prediction.setModelTypeAsResNet()
prediction.setModelPath("/mnt/auto/model/resnet50_weights_tf_dim_ordering_tf_kernels.h5")
prediction.loadModel()

@bottle.route('/image_prediction', method='POST')
def getNextLine():
    postData = json.loads(bottle.request.body.read().decode("utf-8"))
    image = postData.get("image", None)
    image = image.split("base64,")[1]
    # 图片获取
    imagePath = "/tmp/%s" % randomStr(10)
    with open(imagePath, 'wb') as f:
        f.write(base64.b64decode(image))
    # 内容预测
    result = {}
    predictions, probabilities = prediction.predictImage(imagePath, result_count=5)
    for eachPrediction, eachProbability in zip(predictions, probabilities):
        result[str(eachPrediction)] = str(eachProbability)
    return result

@bottle.route('/', method='GET')
def getNextLine():
    return bottle.template('./html/index.html')

app = bottle.default_app()
if __name__ == "__main__":
    bottle.run(host='localhost', port=8080)

而页面代码,则主要是通过HTML与Javascript实现一个便于测试的前端页面:

除此之外,还需明确该项目所必须的依赖:

tensorflow==1.13.1
numpy==1.19.4
scipy==1.5.4
opencv-python==4.4.0.46
pillow==8.0.1
matplotlib==3.3.3
h5py==3.1.0
keras==2.4.3
imageai==2.1.5
bottle==0.12.19

为了更快速的在与阿里云FaaS平台相同的环境下进行依赖安装,以及项目部署,此时可以通过Serverless Devs开发者工具进行部署,在部署之前需要编写资源描述文档:

edition: 1.0.0    
name: imageAi          # 项目名称
access: 'default'         #  秘钥别名

services:
  imageAi: #  服务名称
    component: devsapp/fc
    actions: # 自定义执行逻辑
      pre-deploy: # 在deploy之前运行
        - run: s build --use-docker  # 要运行的命令行
          path: ./ # 命令行运行的路径
      post-deploy: # 在deploy之后运行
        - run: s nas command mkdir /mnt/auto/.s
          path: ./ # 命令行运行的路径
        - run: s nas upload -r -n ./.s/build/artifacts/ai-cv-image-prediction/server/.s/python /mnt/auto/.s/python   # 要运行的命令行
          path: ./ # 命令行运行的路径
        - run: s nas upload -r -n ./src/model  /mnt/auto/model   # 要运行的命令行
          path: ./ # 命令行运行的路径
    props: #  组件的属性值
      region: cn-hangzhou
      service:
        name: ai-cv-image-prediction
        description: 图片目标检测服务
        nasConfig: auto
        vpcConfig: auto
        logConfig: auto
      function:
        name: server
        description: 图片目标检测
        runtime: python3
        codeUri: ./src
        handler: index.app
        memorySize: 3072
        timeout: 60
        environmentVariables:
          PYTHONUSERBASE: /mnt/auto/.s/python
      triggers:
        - name: httpTrigger
          type: http
          config:
            authType: anonymous
            methods:
              - GET
              - POST
              - PUT
      customDomains:
        - domainName: auto
          protocol: HTTP
          routeConfigs:
            - path: /*
项目部署

通过Serverless Devs开发者工具,拉取Docker镜像,进行依赖安装:

s build --use-docker

依赖安装完成之后,可以通过进行项目的部署。部署完成,可以看到系统返回的测试地址::

项目测试

通过测试地址,可以上传一张图片,并进行预测:

可以看到,预测结果和前文在本地执行的结果是一致的。至此,已经成功的将本地的Tensorflow项目部署到了Serverless架构上。

项目优化

本项目采用的是阿里云函数计算的Python运行时。相对来说,该运行时与人工智能项目相结合存在一定的复杂度: