构建包含推理的应用程序所涉及的不仅仅是运行机器学习推理模型。开发者还需要做到以下几点:
MediaPipe框架解决了这些挑战,开发者可以使用它轻松快速地将现有的或新的机器学习模型组合到以图表示的原型中,并将其跨平台实现。开发人员可以配置使用MediaPipe创建的应用程序做到如下几点:
如在增强现实(AR)的应用程序中为了增强用户体验,程序会以高帧频处理诸如视频和音频之类的感官数据。由于处理过程的的过度耦合和低延时要求,很难按照常规应用程序开发方式协调数据处理步骤和推理模型。此外,为不同平台开发同样的应用程序也非常耗时,它通常涉及优化推理和处理步骤以便在目标设备上正确高效地运行。
MediaPipe通过将各个感知模型抽象为模块并将其连接到可维护的图中来解决这些问题。借助MediaPipe,可以将数据流处理管道构建为模块化组件图,包括推理处理模型和媒体处理功能。将视频和音频流数据输入到图中,通过各个功能模块构建的图模型管道处理这些数据,如物体检测或人脸点标注等最后结果数据从图输出。
这些功能使开发者可以专注于算法或模型开发,并使用MediaPipe作为迭代改进其应用程序的环境,其结果可在不同的设备和平台上重现。除了上述的特性,MediaPipe还支持TensorFlow和TFLite的推理引擎,任何TensorFlow和TFLite的模型都可以在MediaPipe上使用。同时在移动端和嵌入式平台,MediaPipe也支持设备本身的GPU加速。
下图是基于MediaPipe构建的的目标检测图:
从图中各个模块的名字可以看出个模块的功能,输入是摄像头采集的视频数据帧通过图中各个模块的处理输出到显示屏上。下图是手机运行效果:
MediaPipe有下面三个主要部分组成:
MediaPipe的核心框架由C++实现,并提供Java以及Objective-C等语言的支持。MediaPipe的主要概念包括:
这些概念中主要是图和计算单元,它们是MediaPipe运行的核心,下面会重点说明它们。
MediaPipe已经包含了多个由Google实现的计算单元,也向用户提供定制新计算单元的基类。并且子图的概念是为了方便用户在多个图中复用已有的通用组件,例如图像数据的预处理、模型的推理以及图像的渲染等,因此一个MediaPipe图中的节点既可以是计算单元,亦可以是子图。子图在不同图内的复用,方便了大规模模块化的应用搭建。
可以看出图是一个有向的数据流管线,一个数据包从数据源进入,然后按照数据流线路流经各个节点直到输出结点完成。
图结构描述通过GraphConfig指定,它通过一个文件的形式存在可以被Graph加载运行,我们可以通过更新GraphConfig配置文件来添加,删除或更改组件的连接。我们还可以在这个文件里配置全局级别设置,以修改图的执行和资源消耗,这对于调整不同平台(例如台式机和移动设备)上的性能非常有用。
另外在TensorFlow,PyTorch,CNTK或MXNet等项目中使用图来定义神经网络模型。但MediaPipe的图起到了补充作用,MediaPipe未定义神经网络的内部结构,而是指定了嵌入一个或多个模型的较大规模的处理图。
计算单元是一个C++类,创建一个计算单元需要用户继承于CalculatorBase类并实现GetContract,Open,Process,Close方法去分别定义计算单元的初始化,数据流的处理,以及在计算单元完成所有运算后的关闭步骤。
假设有一个场景,里面有摄像机,麦克风和光传感器在采集数据并要处理。每个传感器都独立运行,并且按照各自的采样率采集数据,由于各个传感器的采样率不同它们收集并发送数据就不会同步。假如每个传感器的采集输出为:
PacketClonerCalculator的完整代码:
可以看到图显示在左边区域它是一个只读区域,通过鼠标可以缩放并拖动图但不能编辑。右边是文本编辑区可以添加或编辑图描述代码来修改图,这里的代码就是GraphConfig,它可以被保存为一个文本文件然后通过Graph的API来加载这个图。下面的代码是我们又添加一个视频反转(VideoFlip)的计算单元。更新后的图如下所示:
input_stream:"input"output_stream:"output"node{calculator:"VideoClipCalculator"input_stream:"IN:input"output_stream:"clippedVideoOutput"}node{calculator:"VideoFlipCalculator"input_stream:"clippedVideoOutput"output_stream:"OUT:output"}
图配置代码简单说明如下:
可以看到VideoClipCalculator节点使用input作为输入,然后输出clippedVideoOutput,VideoFlipCalculator节点使用clippedVideoOutput作为输入,最后输出output。另外图配置还有另外一些参数配置和命名规则这里就不再说了。
下面这些都是Google利用MediaPipe框架实现的移动端应用示例,当然整个基于MediaPipe的开源项目还有桌面应用示例,浏览器应用示例和GoogleCoral应用示例。
下图就是物体检测的MeidaPipe图,可以看出从上面的视频输入到下面的视频输出整个过程还是有不少计算单元的,其中仅TfLiteInference计算单元基于TensorFlowLite完成推理。
我们从上而下说明一下每个计算单元的作用:
MediaPipe里还有边数据包(Sidepackets),输入策略(Inputpolicies),运行时行为(Runtimebehavior)等等概念就不再说明了,有兴趣可以看官方文档。
可以说是MediaPipe是一个利用“有序管线”图的应用程序开发框架,甚至可以基于它开发一个完全没有机器学习推理的应用程序,但是由于它基于图的这样一个架构使其很适合开发含有推理模型的应用。
MediaPipe用Bazel构建工具来构建应用,库和测试工具,MediaPipe框架及里面的所有示例包括iOS端的都是用这个工具构建的,所有要会使用这个跨平台构建工具。