国外网站视觉设计趋势,为什么我的网站做不起来,wordpress 分类文章,佛冈网站建设简介#xff1a; 本文将会通过一个有趣的 Python 库#xff0c;快速将图像分类的功能搭建在云函数上#xff0c;并且和 API 网关结合#xff0c;对外提供 API 功能#xff0c;实现一个 Serverless 架构的“图像分类 API”。 前言
图像分类是人工智能领域的一个热门话题。… 简介 本文将会通过一个有趣的 Python 库快速将图像分类的功能搭建在云函数上并且和 API 网关结合对外提供 API 功能实现一个 Serverless 架构的“图像分类 API”。 前言
图像分类是人工智能领域的一个热门话题。通俗解释就是根据各自在图像信息中所反映的不同特征把不同类别的目标区分开来的图像处理方法。
它利用计算机对图像进行定量分析把图像或图像中的每个像元或区域划归为若干个类别中的某一种以代替人的视觉判读。
图像分类在实际生产生活中也是经常遇到的而且针对不同领域或者需求有着很强的针对性。例如通过拍摄花朵识别花朵信息、通过人脸比对人物信息等。
通常情况下这些图像识别或者分类的工具都是在客户端进行数据采集在服务端进行运算获得结果也就是说一般情况下都是有专门的 API 实现图像识别的。例如各大云厂商都会为我们有偿提供类似的能力
阿里云图像识别页面 华为云图像识别页面 本文将会通过一个有趣的 Python 库快速将图像分类的功能搭建在云函数上并且和 API 网关结合对外提供 API 功能实现一个 Serverless 架构的“图像分类 API”。
首先和大家介绍一下需要的依赖库ImageAI。通过该依赖的官方文档我们可以看到这样的描述 ImageAI 是一个 python 库旨在使开发人员能够使用简单的几行代码构建具有包含深度学习和计算机视觉功能的应用程序和系统。 ImageAI 本着简洁的原则支持最先进的机器学习算法用于图像预测、自定义图像预测、物体检测、视频检测、视频对象跟踪和图像预测训练。ImageAI 目前支持使用在 ImageNet-1000 数据集上训练的 4 种不同机器学习算法进行图像预测和训练。ImageAI 还支持使用在 COCO 数据集上训练的 RetinaNet 进行对象检测、视频检测和对象跟踪。最终ImageAI 将为计算机视觉提供更广泛和更专业化的支持包括但不限于特殊环境和特殊领域的图像识别。 也就是说这个依赖库可以帮助我们完成基本的图像识别和视频的目标提取虽然他给了一些数据集和模型但是我们也可以根据自身需要对其进行额外的训练进行定制化拓展。通过官方给的代码我们可以看到一个简单的 Demo
# -*- coding: utf-8 -*-
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_count5 )
for eachPrediction, eachProbability in zip(predictions, probabilities):print(str(eachPrediction) : str(eachProbability))
当我们指定的 picture.jpg 图片为 我们在执行之后的结果是
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预测时间较慢精度最高
模型下载地址可参考 Github 地址https://github.com/OlafenwaMoses/ImageAI/releases/tag/1.0
或者参考 ImageAI 官方文档https://imageai-cn.readthedocs.io/zh_CN/latest/ImageAI_Image_Prediction.html
项目 Serverless 化
将项目按照函数计算的需求编写好入口方法以及做好项目初始化同时在当前项目下创建文件夹 model并将模型文件拷贝到该文件夹 项目整体流程 实现代码
# -*- coding: utf-8 -*-from imageai.Prediction import ImagePrediction
import json
import uuid
import base64
import random# Response
class Response:def __init__(self, start_response, response, errorCodeNone):self.start start_responseresponseBody {Error: {Code: errorCode, Message: response},} if errorCode else {Response: response}# 默认增加uuid便于后期定位responseBody[ResponseId] str(uuid.uuid1())print(Response: , json.dumps(responseBody))self.response json.dumps(responseBody)def __iter__(self):status 200response_headers [(Content-type, application/json; charsetUTF-8)]self.start(status, response_headers)yield self.response.encode(utf-8)# 随机字符串
randomStr lambda num5: .join(random.sample(abcdefghijklmnopqrstuvwxyz, num))# 模型加载
print(Init model)
prediction ImagePrediction()
prediction.setModelTypeAsResNet()
print(Load model)
prediction.setModelPath(/mnt/auto/model/resnet50_weights_tf_dim_ordering_tf_kernels.h5)
prediction.loadModel()
print(Load complete)def handler(environ, start_response):try:request_body_size int(environ.get(CONTENT_LENGTH, 0))except (ValueError):request_body_size 0requestBody json.loads(environ[wsgi.input].read(request_body_size).decode(utf-8))# 图片获取print(Get pucture)imageName randomStr(10)imageData base64.b64decode(requestBody[image])imagePath /tmp/ imageNamewith open(imagePath, wb) as f:f.write(imageData)# 内容预测print(Predicting ... )result {}predictions, probabilities prediction.predictImage(imagePath, result_count5)print(zip(predictions, probabilities))for eachPrediction, eachProbability in zip(predictions, probabilities):result[str(eachPrediction)] str(eachProbability)return Response(start_response, result)
所需要的依赖
tensorflow1.13.1
numpy1.19.4
scipy1.5.4
opencv-python4.4.0.46
pillow8.0.1
matplotlib3.3.3
h5py3.1.0
keras2.4.3
imageai2.1.5
编写部署所需要的配置文件
ServerlessBookImageAIDemo:Component: fcProvider: alibabaAccess: releaseProperties:Region: cn-beijingService:Name: ServerlessBookDescription: Serverless图书案例Log: AutoNas: AutoFunction:Name: serverless_imageAIDescription: 图片目标检测CodeUri:Src: ./srcExcludes:- src/.fun- src/modelHandler: index.handlerEnvironment:- Key: PYTHONUSERBASEValue: /mnt/auto/.fun/pythonMemorySize: 3072Runtime: python3Timeout: 60Triggers:- Name: ImageAIType: HTTPParameters:AuthType: ANONYMOUSMethods:- GET- POST- PUTDomains:- Domain: Auto 在代码与配置中可以看到有目录/mnt/auto/ 的存在该部分实际上是 nas 挂载之后的地址只需提前写入到代码中即可下一个环节会进行 nas 的创建以及挂载点配置的具体操作。 项目部署与测试
在完成上述步骤之后可以通过
s deploy
进行项目部署部署完成可以看到结果 完成部署之后可以通过
s install docker
进行依赖的安装 依赖安装完成可以看到在目录下生成了 .fun 的目录该目录就是通过 docker 打包出来的依赖文件这些依赖正是我们在 requirements.txt 文件中声明的依赖内容。
完成之后我们通过
s nas sync ./src/.fun
将依赖目录打包上传到 nas成功之后再将 model 目录打包上传
s nas sync ./src/model
完成之后可以通过
s nas ls --all
查看目录详情 完成之后我们可以编写脚本进行测试同样适用刚才的测试图片通过代码
import json
import urllib.request
import base64
import timewith open(picture.jpg, rb) as f:data base64.b64encode(f.read()).decode()url http://35685264-1295939377467795.test.functioncompute.com/timeStart time.time()
print(urllib.request.urlopen(urllib.request.Request(urlurl,datajson.dumps({image: data}).encode(utf-8)
)).read().decode(utf-8))
print(Time: , time.time() - timeStart)
可以看到结果
{Response: {laptop: 71.43893837928772, notebook: 16.265614330768585, modem: 4.899385944008827, hard_disc: 4.007565602660179, mouse: 1.2981869280338287}, ResponseId: 1d74ae7e-298a-11eb-8374-024215000701}
Time: 29.16020894050598
可以看到函数计算顺利地返回了预期结果但是整体耗时却超乎想象有近 30s此时我们再次执行一下测试脚本
{Response: {laptop: 71.43893837928772, notebook: 16.265614330768585, modem: 4.899385944008827, hard_disc: 4.007565602660179, mouse: 1.2981869280338287}, ResponseId: 4b8be48a-298a-11eb-ba97-024215000501}
Time: 1.1511380672454834
可以看到再次执行的时间仅有 1.15 秒比上次整整提升了 28 秒之多。
项目优化
在上一轮的测试中可以看到项目首次启动和二次启动的耗时差距其实这个时间差主要是函数在加载模型的时候浪费了极长的时间。
即使在本地我们也可以简单测试
# -*- coding: utf-8 -*-import timetimeStart time.time()# 模型加载
from imageai.Prediction import ImagePredictionprediction ImagePrediction()
prediction.setModelTypeAsResNet()
prediction.setModelPath(resnet50_weights_tf_dim_ordering_tf_kernels.h5)
prediction.loadModel()
print(Load Time: , time.time() - timeStart)
timeStart time.time()predictions, probabilities prediction.predictImage(./picture.jpg, result_count5)
for eachPrediction, eachProbability in zip(predictions, probabilities):print(str(eachPrediction) : str(eachProbability))
print(Predict Time: , time.time() - timeStart)
执行结果
Load Time: 5.549695014953613
laptop : 71.43893241882324
notebook : 16.265612840652466
modem : 4.899394512176514
hard_disc : 4.007557779550552
mouse : 1.2981942854821682
Predict Time: 0.8137111663818359
可以看到在加载 imageAI 模块以及加载模型文件的过程中一共耗时 5.5 秒在预测部分仅有不到 1 秒钟的时间。而在函数计算中机器性能本身就没有我本地的性能高此时为了避免每次装载模型导致的响应时间过长在部署的代码中可以看到模型装载过程实际上是被放在了入口方法之外。这样做的一个好处是项目每次执行的时候不一定会有冷启动也就是说在某些复用的前提下是可以复用一些对象的即无需每次都重新加载模型、导入依赖等。
所以在实际项目中为了避免频繁请求实例重复装载、创建某些资源我们可以将部分资源放在初始化的时候进行。这样可以大幅度提高项目的整体性能同时配合厂商所提供的预留能力可以基本上杜绝函数冷启动带来的负面影响。
总结
近年来人工智能与云计算的发展突飞猛进在 Serverless 架构中如何运行传统的人工智能项目已经逐渐成为很多人所需要了解的事情。本文主要介绍了通过一个已有的依赖库ImageAI实现一个图像分类和预测的接口。借助这个例子其实有几个事情是可以被明确的
Serverless 架构可以运行人工智能相关项目Serverless 可以很好地兼容 Tensorflow 等机器学习/深度学习的工具虽然说函数计算本身有空间限制但是实际上增加了硬盘挂载能力之后函数计算本身的能力将会得到大幅度的拓展。
当然本文也算是抛砖引玉希望读者在本文之后可以发挥自己的想象将更多的 AI 项目与 Serverless 架构进行进一步结合。
作者江昱
原文链接
本文为阿里云原创内容未经允许不得转载