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