上一篇中,小編給大家抽絲剝繭的介紹了在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,更懂模型!!!
-
微控制器
+關注
關注
48文章
8340瀏覽量
164229 -
函數
+關注
關注
3文章
4416瀏覽量
67416 -
操作符
+關注
關注
0文章
23瀏覽量
9265 -
tensorflow
+關注
關注
13文章
334瀏覽量
62096
原文標題:TensorFlow Lite Micro玩法升級(二)
文章出處:【微信號:NXP_SMART_HARDWARE,微信公眾號:恩智浦MCU加油站】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
Linux命令中“!”操作符的用法
如何添加自定義單板
如何在TensorFlow Lite Micro中添加自定義操作符(1)
如何在android設備上安裝自定義rom
C++之操作符重載學習的總結
如何在TensorFlow2里使用Keras API創建一個自定義CNN網絡?
自定義視圖組件教程案例
自定義AXI-Lite接口的IP及源碼分析
如何在TensorFlow Lite Micro中添加自定義操作符(2)
評論