图像分类是人工智能领域的热门话题。打开。图像分类是利用计算机对图像进行定量分析,将图像或图像中的每个像素或区域分类为若干类别之一,而不是人的视觉解释。在现实生活中,我们也会遇到图像分类的应用场景,比如常用的通过拍摄花朵来识别花朵信息的方法,以及将人物信息与人脸进行匹配的方法。通常,图像识别或分类工具在客户端采集数据,在服务器端进行计算得到结果。因此,一般都会有专门的API来实现图像识别,云厂商也会收费提供类似的能力:华为云图像标签腾讯云图像分析本文将尝试使用一个有趣的Python库来快速构建图像分类功能在云端,在功能上,结合API网关,对外提供API功能,实现一个Serverless架构的“图片分类API”。一、入门ImageAI首先,我们需要一个依赖库:ImageAI。什么是图像人工智能?它的官方文档是这样描述的:ImageAI是一个python库,旨在使开发人员能够使用简单的几行代码来构建具有深度学习和计算机视觉功能的应用程序和系统。基于简单的原则,ImageAI支持最先进的机器学习算法,用于图像预测、自定义图像预测、对象检测、视频检测、视频对象跟踪和图像预测训练。ImageAI目前支持使用在ImageNet-1000数据集上训练的4种不同机器学习算法进行图像预测和训练。ImageAI还支持使用在COCO数据集上训练的RetinaNet进行对象检测、视频检测和对象跟踪。最终,ImageAI将为计算机视觉提供更广泛、更专业的支持,包括但不限于特殊环境、特殊领域的图像识别。简单理解,ImageAI依赖库可以帮助用户完成基本的图像识别和视频目标提取。不过ImageAI虽然提供了一些数据集和模型,但我们也可以根据自己的需要进行额外的训练和定制化的扩展。ItsofficialcodegivessuchasimpleDemo:fromimageai.PredictionimportImagePredictionimportosexecution_path=os.getcwd()prediction=ImagePrediction()prediction.setModelTypeAsResNet()prediction.setModelPath(os.path.join(execution_path,"resnet50_weights_tf_dim_ordering_tf_kernels").h5prediction.loadModel()predictions,probabilities=prediction.predictImage(os.path.join(execution_path,"1.jpg"),result_count=5)foreachPrediction,eachProbabilityinzip(predictions,probabilities):print(eachPrediction+":"+eachProbability)我们可以在本地进行初步运行,指定图片1.jpg为下图时:可以得到结果:convertible:52.459537982940674sports_car:37.61286735534668pickup:3.175118938088417car_wheel:1.8175017088651657minivan:1.74870286136865622.让ImageAI上云(部署到Serverless架构上)通过Forthedemoabove,wecanconsiderdeployingthismoduletoCloudFunction:First,createaPythonprojectlocally:mkdirimageDemo,thencreateanewfile:vimindex.pyThird,accordingtosomespecialformsofCloudFunction,weTheDemoispartiallytransformedandtheinitializationcodeisplacedintheouterlayer;thepredictionpartisregardedasthepartthatneedstobeexecutedasatrigger,andplacedintheentrymethod(hereismain_handler);thecombinationofcloudfunctionsandAPIgatewayisnotveryfriendlytobinaryfilesupport,soherethroughbase64图像传输;输入参数设置为{“picture”:图片的base64},输出参数设置为:{“prediction”:图片分类结果}。实现代码如下:fromimageai.PredictionimportImagePredictionimportos,base64,randomexecution_path=os.getcwd()prediction=ImagePrediction()prediction.setModelTypeAsSqueezeNet()prediction.setModelPath(os.path.join(execution_path,"squeezenet_weights_tf_dim_ordering_tf_kernels.h5"))prediction.loadModel()defmain_handler(event,context):imgData=base64.b64decode("event[body"])fileName='/tmp/'+"".join(random.sample('zyxwvutsrqponmlkjihgfedcba',5))withopen(fileName,'wb')asf:f.write(imgData)resultData={}predictions,probabilities=prediction.predictImage(fileName,result_count=5)foreachPrediction,eachProbabilityinzip(predictions,probabilities):resultData[eachPrediction]=eachProbabilityreturnresultData为后创建好后,下载依赖模型:SqueezeNet(文件大小:4.82MB,预测时间最短,准确度适中)MicrosoftResearch的ResNet50(文件大小:98MB,预测时间快,准确度高)GoogleBrain团队的InceptionV3(文件大小:91.6MB,预测时间较慢,精度更高)DenseNet121byFacebookAIResearch(文件大小:31.6MB,预测时间较慢,精度最高)由于我们仅将其用于测试,因此选择较小的模型:SqueezeNet:复制地址官方文档中的模型文件:直接使用wget安装:wgethttps://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.yamlimageDemo:component:"@serverless/tencent-scf"inputs:name:imageDemocodeUri:./handler:index.main_handlerruntime:Python3.6region:ap-guangzhoudescription:imagerecognition/classificationDemomemorySize:256timeout:10events:-apigw:name:imageDemo_apigw_serviceparameters:protocols:-httpserviceName:serverlessdescription:imagerecognition/classificationDemoAPIenvironment:releaseendpoints:-path:/imagemethod:ANY完成后,执行sls--debugdeployment,部署过程中会有一个扫码登录,登录后等待即可,完成后可以看到部署地址SS。3.基础测试用Python语言测试,接口地址只是复制+/image,例如:importjsonimporturllib.requestimportbase64withopen("1.jpg",'rb')asf: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"))通过网络搜索图片:gettherunningresult:{"prediction":{"cheetah":83.12643766403198,"Irish_terrier":2.315458096563816,"lion":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.8476998433470726,"teddy":1.6655176877975464,"baboon":1.556277838我们可以看到这个basic/categorized的结果}25839预测成功了。为了证明这个接口的延迟,程序基本可以修改:importurllib.requestimportbase64,timeforiinrange(0,10):start_time=time.time()withopen("1.jpg",'rb')asf: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}}成本:1.5917718410491943{“预测”:{"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秒之间。当然,如果你想对接口性能测试做更多的调整,比如通过并发测试,看看接口在并发下的性能等。至此,我们就完成了Python版的图像识别/分类通过无服务器架构构建的工具。4.总结Serverless架构下有很多人工智能相关的应用。本文通过已有的依赖库实现一个图像分类/预测接口。imageAI依赖库的自由度比较高,可以根据自己的需求定制自己的模型。这篇文章也算是一个介绍,期待更多人通过Serverless架构部署自己的“人工智能”API。
