将训练好的模型部署在嵌入式设备中

1.模型转换与优化

        首先,需要将训练好的模型转换成适合嵌入式设备的格式。例如,如果你的模型是在TensorFlow或PyTorch等框架上训练的,你可能需要将其转换为TensorRT或OpenVINO等可以在嵌入式设备上运行的格式。此外,你还需要对模型进行优化,例如通过量化、剪枝等方法减小模型的大小和计算复杂度,以便在资源有限的嵌入式设备上运行。下面以TensorFlow为例

模型转换:

       首先需要使用TensorFlow Lite Converter将原始TensorFlow模型转换为TensorFlow Lite模型(.tflite格式)

import tensorflow as tf
 
# 转换模型
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) # SavedModel目录的路径
tflite_model = converter.convert()
 
# 保存TF Lite模型
with open('model.tflite', 'wb') as f:
  f.write(tflite_model)

模型量化:

       在进行保存模型后需要对模型进行量化,以减小模型大小和推理时间,它通过降低模型参数的精度来实现,TensorFlow Lite支持将浮点数模型量化为8位整数模型,这可以显著减少模型的大小和运行时的计算复杂性。

       TensorFlow Lite Converter 提供了内置的量化选项,如后训练量化(post-training quantization, PTQ)和量化感知训练(quantization-aware training, QAT)。

动态范围量化:

         权重(float32) 会在训练后量化为 整型(int8),激活会在推断时动态量化,模型大小缩减至原来的四分之一

import tensorflow as tf
 
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
# 启动默认的 optimizations 来量化所有固定参数(权重)
converter.optimizations = [tf.lite.Optimize.DEFAULT] tflite_quant_model = converter.convert()

全整型量化:

整型量化是将32位浮点数 转换为8位定点数。这样可以缩减模型大小并加快推理速度,这对低功耗设备(如MCU)很有价值。仅支持整数的加速器(如 Edge TPU)也需要使用此数据格式。

converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]    # 先启动默认的optimizations将模型权重进行量化
converter.representative_dataset = representative_data_gen  # 使用代表数据集量化模型中间值
# 如果有任何的 ops不能量化,converter 将抛出错误
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] 
# 将输入和输出tensors设置为int8 类型
converter.inference_input_type = tf.int8   # or tf.uint8
converter.inference_output_type = tf.int8  # or tf.uint8
 
tflite_model_quant = converter.convert()

float16量化:

TensorFlow Lite 支持在模型从 TensorFlow 转换到 TensorFlow Lite FlatBuffer 格式期间将权重转换为 16 位浮点值。这样可以将模型的大小缩减至原来的二分之一

import tensorflow as tf
 
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.float16]
tflite_quant_model = converter.convert()

        除去量化方式外,还有其它各种优化模型方法,如稀疏性优化,可以减少模型大小并提高执行效率。这特别适用于具有大量零权重的模型;操作符优化,TensorFlow Lite包含一个优化内核库,该库针对移动设备进行了优化。在转换过程中,原始TensorFlow曹祖偶会被映射到这些优化内核上,从而提高推理速度;模型剪枝,去除模型中不重要的连接或权重的技术,从而减少模型大小和计算复杂性。虽然 TensorFlow Lite Converter 本身不提供剪枝功能,但你可以在转换为 TensorFlow Lite 格式之前使用 TensorFlow 的剪枝 API。

2.测试TensorFlow Lite模型

        在转换后,使用TensorFlow Lite Interpreter在桌面环境中测试模型的准确性和性能,以确保转换没有引入错误。

运行 TensorFlow Lite 模型涉及几个简单步骤:

  1. 将模型加载到内存中。
  2. 基于现有模型构建 Interpreter
  3. 设置输入张量值。(如果不需要预定义的大小,则可以选择调整输入张量的大小。)
  4. 调用推断。
  5. 读取
  6. 输出张量值。

下面代码中对定义模型、保存模型、转换模型、加载和使用TFLite模型的代码

import tensorflow as tf  
  
# 定义一个继承自 tf.Module 的 TestModel 类  
class TestModel(tf.Module):  
  def __init__(self):  
    # 调用父类的构造函数  
    super(TestModel, self).__init__()  
  
  # 使用 tf.function 装饰器定义一个名为 add 的方法,该方法接受一个特定形状的浮点数张量作为输入  
  @tf.function(input_signature=[tf.TensorSpec(shape=[1, 10], dtype=tf.float32)])  
  def add(self, x):  
    '''  
    一个简单的方法,接受单个输入 'x',并返回 'x + 4'。  
    '''  
    # 为了方便,将输出命名为 'result'  
    return {'result': x + 4}  
  
# 指定保存模型的路径和TFLite文件的路径  
SAVED_MODEL_PATH = 'content/saved_models/test_variable'  
TFLITE_FILE_PATH = 'content/test_variable.tflite'  
  
# 实例化 TestModel 类  
module = TestModel()  
# 使用 tf.saved_model.save 方法保存模型,同时指定一个签名(这里命名为 'my_signature')  
tf.saved_model.save(  
    module, SAVED_MODEL_PATH,  
    signatures={'my_signature': module.add.get_concrete_function()})  
  
# 使用 TFLiteConverter 从保存的模型中转换模型  
converter = tf.lite.TFLiteConverter.from_saved_model(SAVED_MODEL_PATH)  
# 执行转换  
tflite_model = converter.convert()  
# 将转换后的模型写入TFLite文件  
with open(TFLITE_FILE_PATH, 'wb') as f:  
  f.write(tflite_model)  
  
# 使用 TFLite Interpreter 加载TFLite模型  
interpreter = tf.lite.Interpreter(TFLITE_FILE_PATH)  
# 获取模型的签名运行器(这里模型只有一个签名,所以默认返回它)  
my_signature = interpreter.get_signature_runner()  
  
# 注意:下面的输入数据形状应该是 [1, 10],但代码中给的是 [1, 1],这是一个错误。  
# 正确的输入应该是形状为 [1, 10] 的张量。  
# 使用签名运行器进行推理,并传入输入数据(这里输入数据形状错误,需要修正)  
# output = my_signature(x=tf.constant([1.0], shape=(1,1), dtype=tf.float32)) # 错误的输入形状  
output = my_signature(x=tf.constant([1.0] * 10, shape=(1, 10), dtype=tf.float32)) # 正确的输入形状  
# 'output' 是一个包含所有推理输出的字典  
# 在这个例子中,我们只有一个输出 'result'  
# 打印输出结果  
print(output['result'])

在TensorFlow中,SignatureDef是SavedModel的一部分,它定义了模型的输入和输出,并允许用户指定如何通过TensorFlow Serving或TensorFlow Lite等工具来调用模型。一个SignatureDef包含一个或多个输入和输出的映射,每个映射都有一个唯一的名称和数据类型。

当你保存一个模型为SavedModel格式时,你可以定义一个或多个SignatureDef,每个SignatureDef代表模型的一个特定调用方式。这使得你可以为模型的不同用途或不同的输入/输出配置定义多个签名。

在TensorFlow Lite中,当你从SavedModel转换模型时,这些SignatureDef会被保留,并可以通过TFLite Interpreter的get_signature_runner方法来访问。这样,你就可以在TFLite中使用与在TensorFlow Serving中相同的模型签名。

简而言之,SignatureDef是模型的一个接口描述,它定义了如何通过特定的输入和输出来调用模型。这对于将模型部署到生产环境并使其易于被各种客户端和服务调用非常有用。

3.准备嵌入式设备环境

        根据你的嵌入式设备(如NVIDIA Jetson系列、Raspberry、PI、Edge TPU设备等)安装必要的软件和库。这可能包括TensorFlow Lite runtime、解释器和其它依赖项。对于某些设备,可能需要交叉编译TensorFlow Lite解释器或使用预编译的二进制文件。拿STM32系列MCU举例,需要安装STM32CubeMX和STM32CubeIDE,这些都可以用于配置硬件和开发固件,同时需要安装TensorFLow Lite for Microcontrollers,主要在C++环境中开发,可以先使用python来转换和优化TensorFlow模型为TensorFlow Lite格式,以及生成用于STM32的C++代码。

4.集成模型到应用中

        将优化后的模型集成到STM32应用中,这涉及到编写代码来加载模型、处理输入数据、运行推理以及处理输出数据。ensorFlow Lite为C++提供了API,因此可以使用C++编写这部分代码。

     1、创建或导入项目

               首先创建或导入一个新的项目,配置好硬件设置,如时钟、引脚分配、中断等。

     2、集成TensorFlow Lite库

              将TensorFlow Lite for Microcontrollers库添加到项目中。这通常涉及将库的头文件和源文件包含到您的项目中。配置项目的构建系统,以确保库文件在编译时被正确链接。

     3、加载模型

  • 将转换和优化后的TensorFlow Lite模型文件(通常以.tflite为扩展名)添加到项目中。
  • 编写代码来加载模型文件到内存中。TensorFlow Lite for Microcontrollers提供了用于加载模型的API。

     4、处理输入数据

  • 根据模型需求,编写代码来处理从传感器或其他数据源接收的输入数据。
  • 输入数据可能需要进行预处理,如缩放、归一化或转换为模型所需的格式。

     5、运行推理

  • 使用TensorFlow Lite for Microcontrollers的API编写代码来运行模型推理。
  • 这通常涉及将输入数据传递给模型,并接收模型的输出。

     6、处理输出数据

  • 编写代码来处理模型的输出数据,并将其转换为对您的应用有意义的信息。
  • 输出数据可能需要进行后处理,如解码、阈值判断或转换为实际应用所需的格式。

     7、集成到主循环

  • 将推理代码集成到您的应用的主循环或事件处理逻辑中。
  • 根据需要定期运行推理,或者响应特定事件或条件触发推理。

     8、调试和测试

  • 在STM32上进行调试和测试,确保模型正确加载、输入数据正确处理、推理正确运行以及输出数据正确解释。
  • 使用调试工具检查内存使用情况、性能瓶颈等,并进行必要的优化。

5.在嵌入式设备上部署

        最后,将应用部署到STM32设备上。这可能需要使用特定的开发工具链(如Keil、IAR等)来编译和烧录您的代码。在部署过程中,可能需要考虑如何管理设备的内存和处理器资源,以确保模型能够高效运行。

  • 23
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GPU深度学习训练后,如何部署嵌入式设备主要涉及模型压缩和转换两方面的问题。 首先,模型压缩是为了减小模型的体积和计算量,以适应嵌入式设备有限的资源。常用的模型压缩方法有量化、剪枝和蒸馏等。量化是指将模型的权重参数由浮点型转换为定点型,从而降低存储和计算开销。剪枝是指通过删除模型一些冗余的连接或参数,减少模型的参数数量和计算量。蒸馏是通过使用一个较大的模型(教师模型)来引导另一个较小的模型(学生模型)学习,以达到模型压缩的目的。 其次,模型转换是将训练好的模型从主机端转移到嵌入式设备上进行部署。常用的模型转换方法包括模型编译和模型优化。模型编译是将训练好的模型转换为适合于嵌入式设备运行的特定格式,如TensorFlow Lite(TFLite)和ONNX等。模型优化是通过针对嵌入式设备的硬件和软件进行优化,提高模型推理的速度和效率。 一旦模型经过压缩和转换后,就可以将其部署嵌入式设备上进行深度学习推理。在部署过程,需要将模型加载到嵌入式设备的内存,并使用相应的推理引擎来执行模型推理。推理引擎会根据模型的结构和参数进行推理计算,并输出相应的结果。 总之,将GPU深度学习训练后的模型部署嵌入式设备可以通过模型压缩和转换来实现,以适应嵌入式设备的资源限制,并借助相应的推理引擎来执行模型推理。这样可以在嵌入式设备上实现高效的深度学习应用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值