云栖君导读:互操作就是在Kotlin中可以调用其他编程语言的接口,只要它们开放了接口,Kotlin就可以调用其成员属性和成员方法,这是其他编程语言所无法比拟的。同时,在进行Java编程时也可以调用Kotlin中的API接口。
现在,机器学习(ML)和人工智能(AI)是IT行业中的热门话题,同样,容器也成为其中的热门话题之一。我们将机器学习和容器都引入到图像中,用实验验证是否会相互协同出色的完成分类任务。我们将使用Tenserflow和Kontena来详细阐述。
研究目标
在实验中设定目标会使实验更具有针对性。在此,我设定了以下目标:
了解机器学习和TensorFlow;
验证机器学习和容器间是否有协同作用;
在Kontena上部署正在运行的机器学习方案。
我的最终设想如下,共分为三个部分:
有一个简单的API:用户可对JPG图像进行分类;
在多个实例上运行机器学习模型,以便按需扩展;
遵循微服务(microservice)架构模式。
完整代码获取地址::
https://github.com/jnummelin/tensorflow-inception-example?spm=a2c4e.11153959.blogcont409451.10.GUdPFa
TensorFlow简介
TensorFlow是一个使用数据流图进行数值计算的开源软件库。图中的节点表示数学运算,边表示节点间流动的多维数据矩阵(张量)。 这种灵活的架构允许你在不重写代码的情况下,将计算部署到计算机桌面、服务器或者移动设备的一个或多个CPU或GPU上。
非常简单,使用TensorFlow训练具有一套训练数据的计算机模型。一旦模型被训练,我们就可以用模型分析未知的数据,如我们这里所说的图像分类。一般来说,模型预测的是输入数据与训练模型中的某些“已知”模式的匹配程度。
在这里,我们不会深入的探索如何训练模型,因为这需要更加深入的学习机器学习的概念,并深入了解TensorFlow系统。更多相关内容你可以查阅TensorFlow的模型培训教程,还可以查阅HBO硅谷是如何开发hotdog or not-dog这款app(识别物体是否为热狗)的。
TensorFlow模型最大的优点是,一旦模型建立起来,就可以很容易使用,而不需要任何冗杂的后端服务器。正如hotdog or not-dog一样,模型本身也是在移动设备上“运行”。
TensorFlow模型和容器
实验的目标之一是找出机器学习和容器之间是否有协同作用。事实证明,二者之间存在协同作用。
TensorFlow允许你先导出一个稍后用在其它地方的预先训练好的模型,这允许你甚至可以在一个移动设备上使用ML模型查看图片是否包含hotdog,这也使容器真正称为传送和运行机器学习模型的绝佳工具。
使用容器的一个看似不错的方法就是使用Docker的新的多阶段构建(multi-stage builds)方案。
步骤一:model-builder下载一个预先训练好的
checkpoint模型文件,然后输出模型供TensorFlow Serving系统使用。
步骤二:将步骤一准备好的模型数据复制到图像上,供TensorFlow Serving使用。所以,最终输出为一个Docker镜像,它包含了预先 打包好的所有东西。因此,我们可以使用一个docker run…命令为我们的机器学习模型服务。如果这不是一个好的协同策略,那么它什么都不是。从一个机器学习新手的角度来说,使用单个命令运行机器学习是一个很不错的方法。
这里,我使用现成的基础镜像,以便节省安装TensorFlow软件包等复杂工作。资源的下载链为:
https://github.com/bitnami/bitnami-docker-tensorflow-serving
https://github.com/bitnami/bitnami-docker-tensorflow-inception
API
TensorFlow Serving系统使用grpc API,由于一般的机器学习比较复杂,API也相应较为复杂。至少它并不适合任何随机客户端程序轻松对一张jpg图像进行分类。使用grpc API就意味着需要编译protobuf IDL’s并发出复杂的请求。所以,我认为这个解决方案的确需要一个更为合适的API,人们或许可以通过网页发送一张图像,并获取分类结果。
如上所述,我最重又设立了一个新的目标,学习一点Go语言。Go语言使用API进入目标列表,所以,编写一个接收jpg图像的API并调用TensorFlow Serving grpc API进行分类就相当简单了。那么,理论和实践是两回事。API本身实际上很容易启动和运行,只有在使用grpc protocol Buffer的生成代码时才会遇到困难。似乎在protocol到Go语言转换中处理多个包时有些问题。由于我在Go语言上完全是个新手,最后我用一个快速检查和替换(search-and-replace)来“修复”一些导入到生成代码中的包。
因此,API只需要将一个jpg文件转换为TensorFlow Serving中的一个grpc请求,然后在JSON中返回给定的分类结果。
运行模型和API
一旦所有的东西都在容器镜像中,在任何容器业务流程系统上对它进行部署就是一件很简单的事情。因此,我打算用Kontena做为部署的目标。
方案中最复杂的部分就是机器学习模型。但是现在,即便是作为一个独立容器运行,事情也变得非常简单了:
这里,我省略了loadbalancer的配置,查看GitHub库可获取更为详细的部署。
测试
在TensorFlow模型前使用简化的API,那么,使用普通的curl就可以很容易的测试图像分类:
score的值越高,分类的精确度越高。实验结果表明,我们的机器学习模型能够很清楚的识别出这张照片是一只熊猫。如下图:
那么它处理这张热狗图像是什么结果呢?
测试结果看起来相当不错,我们的机器学习模型对热狗识别的精确度也很高。
总结
基于容器的TensorFlow模型确实提供了一个较好的部署方法。实验表明,使用上述架构模式,我们可以很轻松的设置一个可扩展的方案供TensorFLow模型使用。但是,使用带有任何客户端软件的模型显然需要某种API封装,这样可以降低客户端处理TensorFLow grpc的复杂性。
在许多情况下,使用预先创建好的模型当然很不现实。和任何学习一样,这是一个需要反馈的过程,放大学习并产生更准确的结果。目前,我正在考虑通过建立一个恒定模型训练器来扩展我的方法,这个模型训练器可以反馈结果。用户可以在一些web UI中选择实例的哪个类是正确的,或者哪个是新发布的类,这会持续的给构建模型提供一些信息。也可以定期导出模型,以便为模型容器触发一个新的模型构建。