Unity导入自定义ONNX模型失败求助:Loop类型未识别错误
问题:TensorFlow转ONNX模型导入Unity Barracuda失败,提示未知Loop类型
我在实现目标检测功能,参考YouTube教程用TensorFlow制作了模型,通过以下命令将SavedModel转为ONNX格式:
python -m tf2onnx.convert --saved-model TensorFlow-model-path --output model.onnx
但将该ONNX模型导入Unity时失败,导入他人的ONNX模型却能成功。报错核心是解析StatefulPartitionedCall/map/while_loop:0层时遇到未知类型Loop,具体错误日志如下:
错误日志1
OnnxImportException: Unknown type Loop encountered while parsing layer StatefulPartitionedCall/map/while_loop:0. Unity.Barracuda.ONNX.ONNXModelConverter.Err (Unity.Barracuda.Model model, System.String layerName, System.String message, System.String extendedMessage, System.String debugMessage) (at Library/PackageCache/com.unity.barracuda@3.0.0/Barracuda/Runtime/ONNX/ONNXModelConverter.cs:3434) Unity.Barracuda.ONNX.ONNXModelConverter.ConvertOnnxModel (Onnx.ModelProto onnxModel) (at Library/PackageCache/com.unity.barracuda@3.0.0/Barracuda/Runtime/ONNX/ONNXModelConverter.cs:2954) Unity.Barracuda.ONNX.ONNXModelConverter.Convert (Google.Protobuf.CodedInputStream inputStream) (at Library/PackageCache/com.unity.barracuda@3.0.0/Barracuda/Runtime/ONNX/ONNXModelConverter.cs:170) Unity.Barracuda.ONNX.ONNXModelConverter.Convert (System.String filePath) (at Library/PackageCache/com.unity.barracuda@3.0.0/Barracuda/Runtime/ONNX/ONNXModelConverter.cs:98) Unity.Barracuda.ONNXModelImporter.OnImportAsset (UnityEditor.AssetImporters.AssetImportContext ctx) (at Library/PackageCache/com.unity.barracuda@3.0.0/Barracuda/Editor/ONNXModelImporter.cs:65) UnityEditor.AssetImporters.ScriptedImporter.GenerateAssetData (UnityEditor.AssetImporters.AssetImportContext ctx) (at <d63e58d1bc4b489593159fa6218bc0e6>:0) UnityEditorInternal.InternalEditorUtility:ProjectWindowDrag(HierarchyProperty, Boolean) UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)
错误日志2
Asset import failed, "Assets/Models/model.onnx" > OnnxImportException: Unknown type Loop encountered while parsing layer StatefulPartitionedCall/map/while_loop:0. Unity.Barracuda.ONNX.ONNXModelConverter.Err (Unity.Barracuda.Model model, System.String layerName, System.String message, System.String extendedMessage, System.String debugMessage) (at Library/PackageCache/com.unity.barracuda@3.0.0/Barracuda/Runtime/ONNX/ONNXModelConverter.cs:3434) Unity.Barracuda.ONNX.ONNXModelConverter.ConvertOnnxModel (Onnx.ModelProto onnxModel) (at Library/PackageCache/com.unity.barracuda@3.0.0/Barracuda/Runtime/ONNX/ONNXModelConverter.cs:2954) Unity.Barracuda.ONNX.ONNXModelConverter.Convert (Google.Protobuf.CodedInputStream inputStream) (at Library/PackageCache/com.unity.barracuda@3.0.0/Barracuda/Runtime/ONNX/ONNXModelConverter.cs:170) Unity.Barracuda.ONNX.ONNXModelConverter.Convert (System.String filePath) (at Library/PackageCache/com.unity.barracuda@3.0.0/Barracuda/Runtime/ONNX/ONNXModelConverter.cs:98) Unity.Barracuda.ONNXModelImporter.OnImportAsset (UnityEditor.AssetImporters.AssetImportContext ctx) (at Library/PackageCache/com.unity.barracuda@3.0.0/Barracuda/Editor/ONNXModelImporter.cs:65) UnityEditor.AssetImporters.ScriptedImporter.GenerateAssetData (UnityEditor.AssetImporters.AssetImportContext ctx) (at <d63e58d1bc4b489593159fa6218bc0e6>:0) UnityEditorInternal.InternalEditorUtility:ProjectWindowDrag(HierarchyProperty, Boolean) UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&) UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
解决方案
- 升级Barracuda版本:你当前使用的是Barracuda 3.0.0,该版本对ONNX Loop算子支持有限,建议升级到最新稳定版,新版本会扩展算子兼容范围。
- 指定低版本ONNX opset转换:TensorFlow转ONNX时默认opset可能过高,修改转换命令指定较低的opset版本(如opset11或opset13):
python -m tf2onnx.convert --saved-model TensorFlow-model-path --output model.onnx --opset 13 - 固化模型形状:模型中的
while_loop通常用于处理动态形状输出,导出TensorFlow模型时指定固定输入尺寸:- 导出SavedModel时添加
input_signature参数明确输入张量形状; - 若使用预训练检测模型,选择静态图版本导出,替换动态循环节点。
- 导出SavedModel时添加
- 简化ONNX模型:用ONNX Simplifier消除冗余节点后再导入Unity:
pip install onnx-simplifier python -m onnxsim model.onnx simplified_model.onnx - 更换模型导出路径:若上述方法无效,可尝试通过TensorFlow Lite中转:先转TFLite格式再转ONNX,或直接在Unity中使用TFLite模型(Unity官方提供TFLite插件支持)。
内容的提问来源于stack exchange,提问作者user19952742
相关产品推荐
相关产品推荐

