Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

Stella981
• 阅读 807

图像分类是人工智能领域的一个热门话题,通俗来讲,就是根据各自在图像信息中反映的不同特征,把不同类别的目标区分开。图像分类利用计算机对图像进行定量分析,把图像或图像中的每个像元或区域划归为若干个类别中的某一种,代替人的视觉判读。

在实际生活中,我们也会遇到图像分类的应用场景,例如我们常用的通过拍照花朵来识别花朵信息,通过人脸匹对人物信息等。通常,图像识别或分类工具都是在客户端进行数据采集,在服务端进行运算获得结果。因此,一般都会有专门的 API 来实现图像识别,云厂商也会有偿提供类似的能力:

  • 华为云图像标签

Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

  • 腾讯云图像分析

Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

本文将尝试通过一个有趣的 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为下图时:

Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

可以得到结果:

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 = 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(文件大小: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

在官方文档复制模型文件地址:

Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

使用wget直接安装:

wget https://github.com/OlafenwaMoses/ImageAI/releases/download/1.0/squeezenet_weights_tf_dim_ordering_tf_kernels.h5

Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

接下来,进行依赖安装:

Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

由于腾讯云 Serveless 产品,在 Python Runtime 中还不支持在线安装依赖,所以需要手动打包依赖,并且上传。在 Python 的各种依赖库中,有很多依赖可能有编译生成二进制文件的过程,这就会导致不同环境下打包的依赖无法通用。

所以,最好的方法就是通过对应的操作系统 + 语言版本进行打包。我们就是在 CentOS+Python3.6 的环境下进行依赖打包。

对于很多 MacOS 用户和 Windows 用户来说,这确实不是一个很友好的过程,所以为了方便大家使用,我在 Serverless 架构上做了一个在线打包依赖的工具,所以可以直接用该工具进行打包:

Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

生成压缩包之后,直接下载解压,并且放到自己的项目中即可:

Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

最后一步,创建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部署,部署过程中会有扫码登陆,登陆之后等待即可,完成之后,就可以看到部署地址。

Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

基本测试

通过 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"))

通过网络搜索一张图片:

Serverless 实战:用 20 行 Python 代码轻松搞定图像分类和预测

得到运行结果:

{
    "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 Framework 试用计划

我们诚邀您来体验最便捷的 Serverless 开发和部署方式。在试用期内,相关联的产品及服务均提供免费资源和专业的技术支持,帮助您的业务快速、便捷地实现 Serverless!

One More Thing

3 秒你能做什么?喝一口水,看一封邮件,还是 —— 部署一个完整的 Serverless 应用?

复制链接至 PC 浏览器访问:https://serverless.cloud.tencent.com/deploy/express

3 秒极速部署,立即体验史上最快的 Serverless HTTP 实战开发!

传送门:

欢迎访问:Serverless 中文网,您可以在 最佳实践 里体验更多关于 Serverless 应用的开发!


推荐阅读:《Serverless 架构:从原理、设计到项目实战》

点赞
收藏
评论区
推荐文章
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
3年前
CSCNN:新一代京东电商广告排序模型
导读:随着电商平台对图像信息的大量引入,通过图像分析来进行广告点击率判断就成了新的趋势。本次分享的主题为CSCNN:新一代京东电商广告排序模型,主要介绍视觉信息在CTR排序模型中的应用。一方面,我们将介绍在工业场景下使用CNN将图像加入CTR模型联合建模的方法;另一方面,我们指出传统用于分类任务的CNN并不适合电商场景。将电商场景中丰富的、具有强视觉先验的"
可莉 可莉
3年前
20 行代码:Serverless 架构下用 Python 轻松搞定图像分类
「图像分类」是人工智能领域的一个热门话题,我们在实际生活中甚至业务的生产环境里,也经常遇到图像分类相似的需求,如何能快速搭建一个图像分类或者内容识别的API呢?我们考虑使用ServerlessFramework(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.c
Stella981 Stella981
3年前
CSS 分类 (Classification)
★★CSS分类属性(Classification)★★⑴CSS分类属性允许你控制如何显示元素,设置图像显示于另一元素中的何处,相对于其正常位置来定位元素,使用绝对值来定位元素,以及元素的可见度。⑵下面是常用的属性以及描述:!(https://oscimg.oschina.net/oscnet/00cb565
Stella981 Stella981
3年前
Dicom关键概念
数据格式    DICOM将信息分组到datasets中,这意味着胸部X射线图像的文件实际上包含文件中的患者ID,因此图像永远不会被错误地与该信息分开。类似的,JPEG等图像格式也可以使用嵌入式tags中。    DICOM数据对象由许多属性组成,包括名字,ID等,还有一个包含图像像素数据的特殊属性。单个DICOM对象只能包含一个包含像素数
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
马尚 马尚
7个月前
使用Python进行简单的图像分类
图像分类是深度学习中的一个常见任务,它可以将图像分到预定义的类别中。本文将介绍如何使用Python和PyTorch库进行简单的图像分类任务。1.准备数据集首先,我们需要准备一个图像数据集,其中包含不同类别的图像。你可以使用自己的数据集,也可以使用公开的数据