(13-4)TensorFlow Lite移动端与嵌入式轻量级开发实战:将元数据添加到 TensorFlow Lite 模型

13.4 将元数据添加到 TensorFlow Lite 模型

TensorFlow Lite元数据为模型描述提供了标准,元数据是关于模型做什么及其输入/输出信息的重要信息来源。元数据由如下两者元素组成:

  1. 在使用模型时传达最佳实践的可读部分
  2. 代码生成器可以利用的机器可读部分,例如 TensorFlow Lite Android 代码生成器 和 Android Studio ML绑定功能。

在TensorFlow Lite托管模型和TensorFlow Hub上发布的所有图像模型中,都已经被填充了元数据。

13.4.1  具有元数据格式的模型

带有元数据和关联文件的TFLite模型的结构如图13-9所示

图13-9  带有元数据和关联文件的TFLite模型

模型中的元数据定义了metadata_schema.fbs,它存储在TFLite 模型架构的 metadata 字段中 ,名称为“TFLITE_METADATA”。某些模型可能包含相关文件,例如分类标签文件。这些文件使用 ZipFile “附加”模式( mode)作为 ZIP 连接到原始模型文件的末尾。TFLite Interpreter 可以像以前一样使用新的文件格式。

在将元数据添加到模型之前,需要安装tflite-support工具

pip install tflite-support

13.4.2  使用Flatbuffers Python API添加元数据

要为TensorFlow Lite任务库中支持的ML任务创建元数据,需要使用TensorFlow Lite元数据编写库中的高级API 。模型元数据的架构由如下三个部分组成:

  1. 模型信息:模型的总体描述以及许可条款等项目。
  2. 输入信息:所需的输入和预处理(如规范化)的描述。
  3. 输出信息:所需的输出和后处理的描述,例如映射到标签。

由于此时生成的TensorFlow Lite仅支持单个子图,所以在显示元数据和生成代码时,TensorFlow Lite 代码生成器 和 Android Studio ML 绑定功能 将使用ModelMetadata.nameandModelMetadata.description实现,而不是使用SubGraphMetadata.nameand SubGraphMetadata.description实现。

(1)支持的“输入/输出”类型

在设计用于输入和输出的 TensorFlow Lite 元数据时,并没有考虑到特定的模型类型,而是考虑了输入和输出类型。模型在功能上具体做什么并不重要,只要输入和输出类型由以下或以下组合组成,TensorFlow Lite 元数据就支持这个模型。

  1. 功能:无符号整数或 float32 的数字。
  2. 图像:元数据目前支持 RGB 和灰度图像。
  3. 边界框:矩形边界框。

(2)打包相关文件

TensorFlow Lite模型可能带有不同的关联文件,例如,自然语言模型通常具有将单词片段映射到单词ID 的 vocab 文件;分类模型可能具有指示对象类别的标签文件。如果没有相关文件(如果有),模型将无法正常运行。

我们可以通过元数据 Python 库将关联文件与模型捆绑在一起,这样新的 TensorFlow Lite 模型将变成了一个包含模型和相关文件的 zip 文件,可以用常用的zip工具解压。这种新的模型格式继续使用相同的文件扩展名“.tflite.”,这与现有的 TFLite 框架和解释器兼容。

另外,关联的文件信息可以被记录在元数据中,根据文件类型和文件附加到对应的位置(即ModelMetadata、 SubGraphMetadata和TensorMetadata)。

(3)归一化和量化参数

归一化是机器学习中常见的数据预处理技术,归一化的目标是将值更改为通用标度,而不会扭曲值范围的差异。模型量化是一种技术,它允许降低权重的精度表示以及可选的存储和计算激活。在预处理和后处理方面,归一化和量化是两个独立的步骤,具体说明如表4-1所示

表4-1  归一化和量化

正常化

量化

MobileNet 中输入图像的参数值示例,分别用于 float 和 quant 模型。

浮动模型:

- mean:127.5

-std:127.5

量化模型:

- mean:127.5

- std:127.5

浮点模型:

- zeroPoint:0

- scale:1.0

定量模型:

- zeroPoint:128.0

- scale:0.0078125f

什么时候调用?

Inputs输入:如果在训练中对输入数据进行了归一化处理,则推理的输入数据也需要进行相应的归一化处理。

Outputs输出输出数据一般不会被标准化。

浮点模型不需要量化。

量化模型在前/后处理中可能需要也可能不需要量化。这取决于输入/输出张量的数据类型。

-float tensors:不需要在前/后处理中进行量化。

- int8/uint8 张量:需要在预处理/后处理中进行量化。

公式

normalized_input = (input - mean) /std

输入量化:

q = f / scale + zeroPoint

输出去量化:

f = (q - zeroPoint) * scale

参数在哪里

由模型创建者填充并存储在模型元数据中,如 NormalizationOptions

由 TFLite 转换器自动填充,并存储在 tflite 模型文件中。

如何获取参数?

通过 MetadataExtractorAPI [2]

通过 TFLite TensorAPI或MetadataExtractorAPI 实现

float 和 quant 模型共享相同的值吗?

是的,float 和 quant 模型具有相同的归一化参数

浮点模型不需要量化。

TFLite 代码生成器或 Android Studio ML 绑定在数据处理中会自动生成吗?

在处理 uint8 模型的图像数据时,有时会跳过归一化和量化步骤。当像素值在 [0, 255] 范围内时,这样做是可以的。但一般来说,应该始终根据适用的归一化和量化参数处理数据。如果在元数据中设置NormalizationOptions参数,TensorFlow Lite 任务库可以为我们解决规范化工作,量化和反量化处理总是被封装。

请看下面的例子演示在图像分类中创建元数据的过程

(1)首先创建一个新的模型信息,代码如下:

from tflite_support import flatbuffers
from tflite_support import metadata as _metadata
from tflite_support import metadata_schema_py_generated as _metadata_fb

""" ... """
"""为图像分类器创建元数据"""

# Creates model info.
model_meta = _metadata_fb.ModelMetadataT()
model_meta.name = "MobileNetV1 image classifier"
model_meta.description = ("Identify the most prominent object in the "
                          "image from a set of 1,001 categories such as "
                          "trees, animals, food, vehicles, person etc.")
model_meta.version = "v1"
model_meta.author = "TensorFlow"
model_meta.license = ("Apache License. Version 2.0 "
                      "http://www.apache.org/licenses/LICENSE-2.0.")

(2)输入/输出信息

接下来介绍如何描述模型的输入和输出签名,自动代码生成器可以使用该元数据来创建预处理和后处理代码。创建有关张​​量的输入或输出信息的代码如下:

#创建输入
input_meta = _metadata_fb.TensorMetadataT()

#创建输出
output_meta = _metadata_fb.TensorMetadataT()

(3)图片输入

图像是机器学习的常见输入类型,TensorFlow Lite元数据支持颜色空间等信息和标准化等预处理信息。图像的尺寸不需要手动指定,因为它已经由输入张量的形状提供并且可以自动推断。实现图片输入的代码如下:

input_meta.name = "image"
input_meta.description = (
    "Input image to be classified. The expected image is {0} x {1}, with "
    "three channels (red, blue, and green) per pixel. Each value in the "
    "tensor is a single byte between 0 and 255.".format(160, 160))
input_meta.content = _metadata_fb.ContentT()
input_meta.content.contentProperties = _metadata_fb.ImagePropertiesT()
input_meta.content.contentProperties.colorSpace = (
    _metadata_fb.ColorSpaceType.RGB)
input_meta.content.contentPropertiesType = (
    _metadata_fb.ContentProperties.ImageProperties)
input_normalization = _metadata_fb.ProcessUnitT()
input_normalization.optionsType = (
    _metadata_fb.ProcessUnitOptions.NormalizationOptions)
input_normalization.options = _metadata_fb.NormalizationOptionsT()
input_normalization.options.mean = [127.5]
input_normalization.options.std = [127.5]
input_meta.processUnits = [input_normalization]
input_stats = _metadata_fb.StatsT()
input_stats.max = [255]
input_stats.min = [0]
input_meta.stats = input_stats

(4)使用 TENSOR_AXIS_LABELS实现标签输出,代码如下:

#创建输出信息
output_meta = _metadata_fb.TensorMetadataT()
output_meta.name = "probability"
output_meta.description = "Probabilities of the 1001 labels respectively."
output_meta.content = _metadata_fb.ContentT()
output_meta.content.content_properties = _metadata_fb.FeaturePropertiesT()
output_meta.content.contentPropertiesType = (
    _metadata_fb.ContentProperties.FeatureProperties)
output_stats = _metadata_fb.StatsT()
output_stats.max = [1.0]
output_stats.min = [0.0]
output_meta.stats = output_stats
label_file = _metadata_fb.AssociatedFileT()
label_file.name = os.path.basename("your_path_to_label_file")
label_file.description = "Labels for objects that the model can recognize."
label_file.type = _metadata_fb.AssociatedFileType.TENSOR_AXIS_LABELS
output_meta.associatedFiles = [label_file]

(5)创建元数据 Flatbuffers,通过如下代码将模型信息与输入输出信息结合起来。

#创建子图信息
subgraph = _metadata_fb.SubGraphMetadataT()
subgraph.inputTensorMetadata = [input_meta]
subgraph.outputTensorMetadata = [output_meta]
model_meta.subgraphMetadata = [subgraph]

b = flatbuffers.Builder(0)
b.Finish(
    model_meta.Pack(b),
    _metadata.MetadataPopulator.METADATA_FILE_IDENTIFIER)
metadata_buf = b.Output()

(6)接下来将元数据和相关文件打包到模型中,在创建元数据 Flatbuffers后,通过以下populate方法将元数据和标签文件写入 TFLite 文件。

populator = _metadata.MetadataPopulator.with_model_file(model_file)
populator.load_metadata_buffer(metadata_buf)
populator.load_associated_files(["your_path_to_label_file"])
populator.populate()

可以将任意数量的关联文件打包到load_associated_files模型中,但是,至少需要打包元数据中记录的那些文件。在这个例子中,打包标签文件是强制性的。

(7)可视化元数据

可以使用Netron来可视化元数据,或者可以使用以下命令将元数据从 TensorFlow Lite 模型读取为JSON格式的MetadataDisplayer:

displayer = _metadata.MetadataDisplayer.with_model_file(export_model_path)
export_json_file = os.path.join(FLAGS.export_directory,
                    os.path.splitext(model_basename)[0] + ".json")
json_file = displayer.get_metadata_json()
#可选:将元数据写入JSON文件
with open(export_json_file, "w") as f:
  f.write(json_file)

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
基于TensorFlow Lite移动端实现人声识别是一种利用机器学习和深度学习的技术,通过训练模型来识别和分析人的声音。TensorFlow Lite是一个针对移动和嵌入式设备的轻量级解决方案,可以在资源受限的环境下运行训练好的模型。 实现人声识别的过程可以分为以下步骤: 1. 数据收集和准备:收集需要识别的人声数据,并进行数据预处理,例如降噪、归一化和特征提取等。 2. 模型训练:使用TensorFlow框架进行模型的训练。可以通过卷积神经网络(CNN)和循环神经网络(RNN)等深度学习模型对特征进行学习和分类。 3. 模型转换:使用TensorFlow Lite将训练好的模型转换成适用于移动设备的.tflite格式。 4. 移动端集成:将转换后的模型集成到移动应用程序中,并利用TensorFlow Lite提供的API进行调用。可以使用Java或者Kotlin编写移动应用程序,并通过引入TensorFlow Lite库进行模型的加载和推断。 5. 人声识别:在移动设备上运行应用程序,通过录制人声并输入到模型中进行推断,从而实现人声的识别和分类。 基于TensorFlow Lite的人声识别在移动端具有较小的模型体积和快速的推断速度,适用于嵌入式设备和资源受限的环境。通过移动端的人声识别,可以实现一系列应用场景,例如语音助手、语音命令和声纹识别等,为用户提供更加智能和便捷的交互体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值