0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何在TensorFlow Lite Micro中添加自定义操作符(2)

恩智浦MCU加油站 来源:恩智浦MCU加油站 2025-12-26 10:53 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

上一篇中,小编给大家抽丝剥茧的介绍了在TFLm中实现一个算子所涉及的文件,以及每个文件的具体作用,包括:功能实现,算子解析等。那么本篇就带着大家一起看下注册机制是怎么实现的?我们还是先以reshape算子进行说明,如何将reshape算子注册到解析器中,接下来介绍如果我们想自定义一个算子需要干些什么。

操作符注册到解析器

1.1 在 MicroMutableOpResolver 中添加注册方法

文件位置:`micro/micro_mutable_op_resolver.h`,在类定义中添加以下方法:

TfLiteStatusAddReshape() {
returnAddBuiltin(BuiltinOperator_RESHAPE,
          tflite::Register_RESHAPE(),ParseReshape);
}

注册方法说明:

AddBuiltin 函数:MicroMutableOpResolver 的核心方法,用于注册内置操作符

BuiltinOperator_RESHAPE:操作符的唯一标识符,与 FlatBuffer schema 中的定义一致

Register_RESHAPE():返回操作符的注册信息,包含执行函数指针

ParseReshape:参数解析函数指针,用于从模型文件中解析参数

1.2 在全局解析器中注册

文件位置:`micro/all_ops_resolver.cpp`,在 `AllOpsResolver` 构造函数中添加:

AddReshape();

全局注册说明:

`AllOpsResolver` 包含了所有标准 TFLite 操作符

适用于需要完整操作符支持的应用场景

会增加代码大小,但提供最大的模型兼容性

添加新操作符的完整步骤

步骤 1:创建内核实现文件

创建文件:`micro/kernels/your_op.cpp`

1. 包含必要的头文件:

#include"tensorflow/lite/c/builtin_op_data.h"
 #include"tensorflow/lite/c/common.h"
 #include"tensorflow/lite/micro/kernels/kernel_util.h"
 // 其他必要的头文件

2. 定义命名空间和常量:

namespacetflite {
 namespaceops {
 namespacemicro {
 namespaceyour_op {
 constexprintkInputTensor =0;
 constexprintkOutputTensor =0;
 // 其他常量定义

3. 实现核心函数:

`Prepare` 函数:验证参数,计算输出形状

`Eval` 函数:执行实际计算

可选的 `Init` 函数:如果需要持久化数据

4. 创建注册函数:

TfLiteRegistration_V1Register_YOUR_OP() {
  returntflite::RegisterOp(Init,Prepare,Eval);
 }

步骤2:注册操作符

修改文件:`micro/micro_mutable_op_resolver.h`

在类定义中添加注册方法:

TfLiteStatusAddYourOp() {
returnAddBuiltin(BuiltinOperator_YOUR_OP,
          tflite::Register_YOUR_OP(),ParseYourOp);
}

修改文件:`micro/all_ops_resolver.cpp`

在构造函数中添加:

AddYourOp();
关键注意事项

内存管理最佳实践

1. 临时张量管理:

// 正确的临时张量使用方式
 TfLiteTensor* input = micro_context->AllocateTempInputTensor(node,0);
 // 使用张量...
 micro_context->DeallocateTempTfLiteTensor(input); // 必须释放

2. 持久化内存 vs 临时内存:

持久化内存:用于存储操作符参数、权重等需要长期保存的数据

临时内存:用于计算过程中的中间结果,使用后立即释放

3. 内存对齐:

微控制器对内存对齐有严格要求

使用 `MicroArenaBufferAlignment()` 获取正确的对齐值

错误处理规范

1. 参数验证:

TF_LITE_ENSURE(context, condition);     // 条件检查
 TF_LITE_ENSURE_EQ(context,actual, expected);// 相等性检查
 TF_LITE_ENSURE_STATUS(status);        // 状态码检查

2. 错误报告:

TF_LITE_KERNEL_LOG(context,"Error message with details");

3. 状态码使用:

`kTfLiteOk`:操作成功

`kTfLiteError`:一般错误

`kTfLiteDelegateError`:委托相关错误

性能优化策略

1. 避免重复计算:

在 Prepare 阶段完成形状计算

缓存经常使用的计算结果

2. 内存访问优化:

尽量使用连续内存访问模式

避免频繁的小块内存分配

3. 原地操作:

当可能时,使用原地操作减少内存拷贝

检查输入输出是否可以共享内存

4. 数据类型优化:

支持量化数据类型(int8, uint8)

针对不同数据类型提供优化实现

通过遵循以上流程,我们就可以是现在 TensorFlow Lite Micro中添加自定义操作符的操作了,并确保其在资源受限的微控制器环境中稳定高效地运行。

这样一来,就可以不被TFLm的原生算子的约束,放开手脚运行更好的模型。一起探讨,让我们更懂TFLm,更懂模型!!!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 微控制器
    +关注

    关注

    49

    文章

    8909

    浏览量

    166036
  • 函数
    +关注

    关注

    3

    文章

    4423

    浏览量

    68036
  • 操作符
    +关注

    关注

    0

    文章

    23

    浏览量

    9317
  • tensorflow
    +关注

    关注

    13

    文章

    336

    浏览量

    62444

原文标题:TensorFlow Lite Micro玩法升级(二)

文章出处:【微信号:NXP_SMART_HARDWARE,微信公众号:恩智浦MCU加油站】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux命令“!”操作符的用法

    Linux的'!'符号或操作符可以用作逻辑否定运算,也可以用于在历史记录获取命令并进行修改或运行以前执行过的命令。
    发表于 07-05 10:07 2512次阅读

    如何添加自定义单板

    在开发过程,用户有时需要创建自定义板配置。本节将通过一个实例讲解用户如何创建属于自己的machine,下面以g2l-test.conf为例进行说明。
    的头像 发表于 03-12 14:43 1622次阅读

    何在TensorFlow Lite Micro添加自定义操作符(1)

    来支持各种神经网络层的计算。也就是说,我们不仅可以使用内嵌的算子运算,还可以自己注册一个新的算子,更加的灵活。本期就将用两期的文章以 `reshape.cpp` 为例,详细说明如何在 TensorFlow Lite
    的头像 发表于 12-26 10:34 5879次阅读

    何在e203 SOC添加自定义外设

    何在E203 添加自定义的外设,困扰已久,以下是一个从别处借鉴而来的方法: 1、设计好自定义外设的RTL后,在其中
    发表于 10-20 10:38

    何在android设备上安装自定义rom

    完成后,请执行相同的操作,但不要选择自定义rom,而是选择间隙。安装间隙之前需要使用一些自定义rom,您可以从自定义rom的开发人员网页上了解,如果他们没有提及任何相关内容,只需在
    的头像 发表于 11-05 10:48 6390次阅读

    C++之操作重载学习的总结(二)

    复数的概念可以通过自定义类实现;复数的运算操作可以通过操作符重载实现;赋值操作符只能通过成员函数实现;
    的头像 发表于 12-24 16:26 1219次阅读

    C++之操作符重载学习的总结

    操作符重载是c++的强大特性之一;操作符重载的本质是通过函数扩展操作符的功能;operator 关键字是实现操作符重载的关键。
    的头像 发表于 12-24 16:36 1408次阅读

    何在LabVIEW实现自定义控件

    本文档的主要内容详细介绍的是如何在LabVIEW实现自定义控件。
    发表于 01-14 17:17 50次下载
    如<b class='flag-5'>何在</b>LabVIEW<b class='flag-5'>中</b>实现<b class='flag-5'>自定义</b>控件

    何在TensorFlow2里使用Keras API创建一个自定义CNN网络?

    概述 本示例工程我们会在 TensorFlow2 下使用 Keras API 创建一个自定义 CNN 网络,在 Vitis-AI 1.3 环境下编译成 Xilinx DPU 上运行的模型文件,并在
    的头像 发表于 04-15 11:36 3036次阅读

    自定义视图组件教程案例

    自定义组件 1.自定义组件-particles(粒子效果) 2.自定义组件- pulse(脉冲button效果) 3.自定义组件-progr
    发表于 04-08 10:48 16次下载

    教程 2添加特征-自定义配置文件创建

    教程 2添加特征 - 自定义配置文件创建
    发表于 03-15 19:39 0次下载
    教程 <b class='flag-5'>2</b>:<b class='flag-5'>添加</b>特征-<b class='flag-5'>自定义</b>配置文件创建

    教程 2添加特征-自定义配置文件创建

    教程 2添加特征 - 自定义配置文件创建
    发表于 07-06 18:50 0次下载
    教程 <b class='flag-5'>2</b>:<b class='flag-5'>添加</b>特征-<b class='flag-5'>自定义</b>配置文件创建

    添加自定义属性控制fridaserver启动和停止

    添加自定义属性控制fridaserver启动和停止
    的头像 发表于 08-09 10:08 3142次阅读
    <b class='flag-5'>添加</b><b class='flag-5'>自定义</b>属性控制fridaserver启动和停止

    何在Matlab自定义Message

    自定义Message 当我们的 message 消息比较复杂时,通常要用到自定义的 message 消息,MATLAB 2020b以上的版本自带了ROS Toolbox Interface
    的头像 发表于 11-15 18:12 2871次阅读
    如<b class='flag-5'>何在</b>Matlab<b class='flag-5'>中</b><b class='flag-5'>自定义</b>Message

    “+”操作符的使用技巧

    这篇写个平时易被忽略的小知识点,一元 + 操作符的使用技巧。
    的头像 发表于 12-28 13:27 1641次阅读