TensorFlow Lite Acemyzoe

TensorFlow Lite

TensorFlow Lite 专注小型设备,可帮助开发者在移动设备、嵌入式设备和 IoT 设备上运行 TensorFlow 模型。它支持设备端机器学习推断,延迟较低,并且模型形成的的二进制文件很小。

为什么要在端侧做机器学习?

设备无网络或低带宽、低延迟要求、低功耗要求、保护用户隐私。

应用于安卓和ios、嵌入式系统(如Raspberry Pi)、硬件加速器(如Edge TPU)、微控制器(MCU)

前沿NLP模型:MobileBERT、ALBERT

前沿视觉模型:EfficientNet-lite

应用领域:文字(分类、问答),语音(检测、语音合成、语音识别)、图片(目标检测、目标定位、字符OCR识别、手势识别、人脸建模、图像分割、风格迁移、聚类、压缩、超分),音频(翻译、声音合成),内容(视频合成、文本生成、音频生成)

TFlite Model Maker 迁移学习库

略略略

!pip install tflite_model_maker
import tflite_model_maker
# 1.load data
data = tflite_model_maker.ImageClassifierDataLoader.from_folder('./pic/')
# 2.customize the model
model = tflite_model_maker.image_classifier.create(data)
# 3.evaluate the model
loss,accuracy = model.evaluate()
# 4.export the tflite
model.export('./model.tflite')

TensorFlow Lite 主要组件:

  • TensorFlow Lite 转换器,它可将 TensorFlow 模型转换为高效形式以供解释器使用,并可引入优化以减小二进制文件的大小和提高性能。
    • GraphDef转化-常量折叠、算子融合、模型量化-输出模型基于Flatbuffers
    • tensorflow(estimator or keras)-> saved model ->tflite转化器 -> tflite模型
  • TensorFlow Lite 解释器,它可在手机、嵌入式 Linux 设备和微控制器等很多不同类型的硬件上运行经过专门优化的模型。
    • 更少依赖库
    • 文件更小(不带算子~100k,带120个算子~900k)
    • 快速加载、静态内存规划、静态执行规划
  • 算子
    • 张量(tensor),即任意维度的数据,一维、二维、三维、四维等数据统称为张量。而张量的流动则是指保持计算节点不变,让数据进行流动。这样的设计是针对连接式的机器学习算法,比如逻辑斯底回归,神经网络等。连接式的机器学习算法可以把算法表达成一张图,张量从图中从前到后走一遍就完成了前向运算;而残差从后往前走一遍,就完成了后向传播。
    • 在TF的实现中,机器学习算法被表达成图,图中的节点是算子(operation),节点会有0到多个输出。每个算子都会有属性,所有的属性都在建立图的时候被确定下来,比如,最常用的属性是为了支持多态,比如加法算子既能支持float32,又能支持int32计算。
  • 硬件加速器接口

TensorFlow Lite 工作流:

  1. 选择模型

    使用自己的 TensorFlow 模型,在线查找模型,或者预训练模型中选择一个模型直接使用或重新训练。

  2. 转换模型

    自定义模型使用 TensorFlow Lite 转换器将模型转换为 TensorFlow Lite 格式,只需几行 Python 代码就能搞定。

    import tensorflow as tf
    converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
    tflite_model = converter.convert()
    open("converted_model.tflite", "wb").write(tflite_model)
    

    Netron是可视化TensorFlow Lite模型的最简单方法。

  3. 部署到设备

    推断是通过模型运行数据以获得预测的过程。它需要一个模型,一个解释器和输入数据。

    使用 TensorFlow Lite 解释器(具有支持多种语言的 API)在设备端运行您的模型。

    解释器可在多个平台上工作,并提供了一个简单的API,用于运行Java,Swift,Objective-C,C ++和Python中的TensorFlow Lite模型。

    嵌入式Linux是用于部署机器学习的重要平台。要开始使用Python对TensorFlow Lite模型执行推理,请遵循Python quickstart

    要改为安装C ++库,请参阅Raspberry Pi基于Arm64的板的构建说明 (适用于Odroid C2,Pine64和NanoPi等板)。

  4. 优化模型

    TensorFlow Lite提供了一些工具 模型优化工具包来优化模型的大小和性能,而对精度的影响通常很小。优化的模型可能需要稍微更复杂的训练,转换或集成。

    模型优化的目标是在给定设备上达到性能,模型尺寸和精度的理想平衡。

    通过降低模型中值和运算的精度,量化可以减少模型的大小和推理所需的时间。

    import tensorflow as tf
    converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
    converter.optimizations = [tf.lite.Optimize.DEFAULT] # 动态范围量化
    tflite_quantized_model = converter.convert()
    open("converted_model.tflite", "wb").write(tflite_quantized_model)
    

推断/推理

TensorFlow Lite解释器旨在实现精简和快速。解释器使用静态图排序和自定义(较少动态)内存分配器,以确保最小的负载,初始化和执行延迟。

  1. 载入模型

    .tflite模型加载到内存中,该内存包含模型的执行图。

  2. 转换数据

    模型的原始输入数据通常与模型期望的输入数据格式不匹配。例如,您可能需要调整图像大小或更改图像格式以与模型兼容。

  3. 运行推断

    此步骤涉及使用TensorFlow Lite API执行模型。涉及几个步骤,例如构建解释器和分配张量。

  4. 解释输出

    当您从模型推断中收到结果时,必须以有意义的方式解释张量。

    例如,模型可能只返回概率列表。您可以将概率映射到相关类别并将其呈现给最终用户。

在Python中加载并运行模型

tf.lite.Interpreter 加载模型并运行推理。

# 使用Python解释器加载 .tflite文件并使用随机输入数据运行推理
import numpy as np
import tensorflow as tf

# Load the TFLite model and allocate tensors.
interpreter = tf.lite.Interpreter(model_path="converted_model.tflite")
interpreter.allocate_tensors()

# Get input and output tensors.
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

# Test the model on random input data.
input_shape = input_details[0]['shape']
input_data = np.array(np.random.random_sample(input_shape), dtype=np.float32)
interpreter.set_tensor(input_details[0]['index'], input_data)

interpreter.invoke()

# The function `get_tensor()` returns a copy of the tensor data.
# Use `tensor()` in order to get a pointer to the tensor.
output_data = interpreter.get_tensor(output_details[0]['index'])
print(output_data)

要使用Python快速运行TensorFlow Lite模型,可以仅安装TensorFlow Lite解释程序,而不是安装所有TensorFlow软件包。

import tflite_runtime.interpreter as tflite
interpreter = tflite.Interpreter(model_path=args.model_file)

在C ++中加载并运行模型

在C ++中,模型存储在 FlatBufferModel 类中。

// Load the model
std::unique_ptr<tflite::FlatBufferModel> model =
    tflite::FlatBufferModel::BuildFromFile(filename);

// Build the interpreter
tflite::ops::builtin::BuiltinOpResolver resolver;
std::unique_ptr<tflite::Interpreter> interpreter;
tflite::InterpreterBuilder(*model, resolver)(&interpreter);

// Resize input tensors, if desired.
interpreter->AllocateTensors();

float* input = interpreter->typed_input_tensor<float>(0);
// Fill `input`.

interpreter->Invoke();

float* output = interpreter->typed_output_tensor<float>(0);

模型优化工具TFMOT

边缘设备通常具有有限的内存或计算能力。可以对模型应用各种优化,以便可以在这些约束条件下运行它们。另外,一些优化允许使用专用硬件来加速推理。

TensorFlow Lite和 TensorFlow模型优化工具包 提供了可将优化推理的复杂性降至最低的工具。

开发流程

模型优化领域涉及多种技术:

  • 通过剪枝和结构化剪枝减少参数数量。
  • 通过量化降低表示法精度。float32 -> int8
  • 将原始模型拓扑更新为更高效的拓扑,后者的参数数量更少或执行速度更快。例如,张量分解方法和蒸馏

模型优化可以通过几种主要方法来帮助应用程序开发。

  1. 缩小尺寸 size_reduction :量化都可以减小模型的大小,这可能会牺牲一些准确性。修剪和聚类可以通过使其更易于压缩来减小下载模型的大小。

  2. 减小延迟 latency_reduction : 延迟是对给定模型运行单个推理所花费的时间。可以通过简化推断过程中发生的计算来使用量化来减少等待时间,这可能会牺牲一些准确性。

  3. 加速器兼容 accelerator_compatibility :某些硬件加速器(例如 Edge TPU)可以使用经过正确优化的模型以极快的速度运行推理。通常,这些类型的设备要求以特定方式量化模型。

  4. 权衡取舍 trade-offs :TensorFlow Lite当前支持通过量化,修剪和聚类进行优化。

量化

通过降低用于表示模型参数的数字的精度来工作,这些参数默认为32位浮点数。

训练后量化 Post-training quantization 可以在已经训练好的浮动TensorFlow模型上执行,并在TensorFlow Lite转换期间应用。

import tensorflow as tf
# 半精度浮点量化
# 只需设置参数无需训练数据
# 所有float32参数转为float16,实际运算根据硬件支持情况而定(比如GPU支持float16)
saved_model = "./model/"
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.lite.constants.FLOAT16]
tflite_model = converter.convert()
open("model.tflite","wb").write(tflite_model)

# 混合量化
# 只需设置参数无需训练数据
# 参数转为int8或者float32,实际运算根据硬件支持情况而定,不符合规范的算子会使用float32计算。
saved_model = "./model/"
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
open("model.tflite","wb").write(tflite_model)

# 纯整数量化
# 效果较好。需要少量训练数据,比如100个。
# 参数转为int8,实际运算根据硬件支持情况而定(支持CPU、DSP、NPU),不符合规范的算子会使用float32计算。
saved_model = "./model/"
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
def data_generator():
    for i in range(calibration_step):
        # get sample input data
        yield [input_sample]
converter.representative_dataset = data_generator()
tflite_model = converter.convert()
open("model.tflite","wb").write(tflite_model)

训练中量化(量化感知训练)

重写计算图来模拟量化推理

在前项推理的时候插入伪量化节点

剪枝

剪枝工作原理是删除模型中对其预测影响很小的参数。

  • 模型训练时,移除权重小于某阈值的连接。密集张量将变得稀疏(用零填充)。
  • 稀疏度为50%时可忽略准确率损失

权重聚集

权重聚集 工作方式是将模型中每个图层的权重分组为预定义数量的簇,然后共享属于每个单独簇的权重的质心值。这减少了模型中唯一权重值的数量,从而降低了其复杂性。可以更有效地压缩集群模型,从而提供类似于修剪的部署优势。

  • 由Arm贡献代码
  • 将各权重按预先设置好的中心数值取代权重
  • 牺牲少量精度来降低需要存储的浮点数
  • arm NPU可支持硬件加速

硬件加速器

TFlite Delegates

给定一个模型计算图,将原本由CPU执行的一部分或全部算子让‘另一个设备’执行,如CPU或其他硬件(GPU、DSP、NPU等)

  • 使用硬件AI加速器能带来更好的性能功耗比,GPU比CPU浮点实现快2-7倍,DSP比CPU耗电量少70%。
  • Delegates提供另一种优化CPU算子实现的方式,提供一种解耦的方式来充分利用TFlite(基于TFlite构造需要的功能)

TensorFlow Extended (TFX)

https://zhuanlan.zhihu.com/p/269133610

https://tensorflow.google.cn/tfx

在产品中使用ML的要求:

  1. 为监督学习获取标记好的数据,并确保数据集全面覆盖所有可能的输入。
  2. 需要在最小化特征集的维度的同时最大化其预测信息。
  3. 需要考虑到一些特殊情况,保证产品的公正性。
  4. 为数据的生命周期管理制定计划。这是一个动态的解决方案,随着新数据的输入和条件改变,它会不断演变。
  5. 应用投入至生产环境中需要满足任何生产级应用的全部需求,包括可扩展性、一致性、模块化、可测试性和安全性。

TensorFlow Extended 从提取数据开始,然后经过数据验证、特征工程、训练、评估和提供服务。

TensorFlow Extended 流水线由一系列组件构成,组件主要包含三个部分:Driver、Executor 和 Publisher。其中 Driver 和 Publisher 主要是模板代码,Executor 是插入代码并制定操作的地方。

Driver 会检查组件的状态并决定需要完成的工作,同时协调作业执行步骤并将元数据返回给 Executor。Publisher 会获取 Executor 的执行结果并更新存储的元数据,而 Executor 才是每个组件实际工作的地方。

为确保所有组件井然有序,同时便于管理好流水线,需要使用到调度器 (Orchestrator) 。调度器是用来整合机器学习流水线、定义流水线中组件的序列并管理其执行。它提供了一个管理界面,可以用来触发任务并监控组件。如果仅需启动流水线的下一阶段,使用任务感知架构即可。当前一个组件完成任务后,就会立即自动启动下一个组件。

TensorFlow Extended 使用 ML - Metadata (MLMD) 来实现元数据存储,这是一个用于定义、存储和查询 机器学习流水线的元数据的开源库。MLMD 会将元数据存储在所关联的后端。目前的版本支持 SQLite 和 MySQL。

首先,MLMD会存储与已训练模型相关的信息、训练模型时使用的数据及其评估结果,这类元数据称为 “Artifact”。接下来在每一个组件的每一次运行时保存它的执行记录。最后,我们还会保存数据对象在流水线中的起源。

TensorFlow Extended 里面的标准组件

Apache Beam 是一个统一编程模型,支持分布式处理的流水线框架。大多数的 TensorFlow Extended 组件运行在 Apache Beam 之上。

当您将这些组件整合到一起,并使用调度器进行管理时,您就拥有了一个 TensorFlow Extended 流水线。您可在一端接收数据,在另一端将 SavedModel 推送到一个或多个部署目标中。这些部署目标包括模型存储区,如 TensorFlow Hub、使用 TensorFlow JS 的 JavaScript 环境、使用 TensorFlow Lite 的原生移动应用、使用 TensorFlow Serving 的应用系统,或上述全部。

  • 读取数据

首先,使用 ExampleGen 提取输入数据。ExampleGen 是在 Beam 上运行的组件之一。该组件会从各类支持的来源和类型中读取数据,同时将其划分为训练数据与评估数据,并将其格式转换为 tf.examples。ExampleGen 的配置过程十分简单,仅需两行 Python 代码。

接着,StatisticsGen 会使用 Beam 对数据进行遍历(即一个完整的 epoch),并为每个特征进行描述统计。

下一个组件 SchemaGen 也使用 TensorFlow Data Validation 库。该组件对 StatisticsGen 处理过的统计数据,并尝试推断特征的基本属性,包括特征值的数据类型、值的范围和类别。

接下来,组件 ExampleValidator 会获取 StatisticsGen 的统计数据和结构(可以是 SchemaGen 直接输出的结果或用户调整后的结果),并查找问题。该组件会查找不同类别的异常,包括丢失的值或与模式不匹配的值、训练-应用偏差、数据偏移,并生成异常报告。

  • 特征工程

Transform 组件使用 Apache Beam 来执行特征工程转换,如创建词汇表或执行主成分分析 (PCA)。

Transform 会输出包含(计算一个特征的中间值或标准差)这些常量和算子的 TensorFlow 计算图。

Transform 会在训练环境、实际应用环境或应用程序内(运行模型的任何地方)使用完全相同的代码,从而消除训练 / 应用偏差。

  • 训练模型

Trainer 会接收 Transform 的转换图和数据,以及 SchemaGen 的结构,并使用建模代码训练模型。

在训练完成时,Trainer 会保存两个不同的 SavedModel。一个是 SavedModel,用于部署至生产环境;而另一个为 EvalSavedModel,用于分析模型性能。

要监控和分析训练过程,可以使用 TensorBoard。在此界面下,可以查看当前的模型训练运行情况,或比较多个模型训练运行的结果。

  • 评估模型

Evaluator 组件会接收 Trainer 创建的 EvalSavedModel 和原始输入数据,并使用 Beam 和 TensorFlow 模型分析库进行深入研究。

在使用模型期间,每位用户的体验都取决于其个人数据点。您的模型可能在您的整个数据集上表现优异,但如果在用户提供的数据点上表现糟糕,则用户体验便会很差。

ModelValidator 组件会使用 Beam 进行该模型与生产环境内的现有模型的比较,通过定义的标准来决定是否将新模型投入生产。

如果 ModelValidator 确定您的新模型已经可以投入生产,则 Pusher 会完成将其部署到目标环境的工作。这些目标可能是 TensorFlow Lite(若正在开发移动应用)、TensorFlow JS(若要部署至 JavaScript 环境)、TensorFlow Serving(若要部署至应用系统)或以上所有环境。