SSD MobileNet训练的手语检测TFLite模型在Flutter运行时形状不匹配报错
错误根因
报错本质是TFLite模型输出张量的顺序和Flutter tflite插件SSD检测逻辑预设的输出顺序不匹配,插件认为第2个输出张量应该是形状为[1, 检测数, 4]的检测框,但你当前模型第2个输出是形状为[1, 10]的分类/置信度张量,所以形状校验失败。
第一步:确认模型输出张量详情
运行以下Python代码查看你现有TFLite模型的所有输出的顺序、名称、形状:
import tensorflow as tf interpreter = tf.lite.Interpreter(model_path="替换为你的tflite模型文件路径") interpreter.allocate_tensors() output_details = interpreter.get_output_details() for idx, out in enumerate(output_details): print(f"输出索引: {idx}, 名称: {out['name']}, 形状: {out['shape']}")
正常SSD模型的4个输出分别对应:
- 检测框坐标:形状为
[1, 最大检测数, 4] - 检测类别ID:形状为
[1, 最大检测数] - 检测置信度:形状为
[1, 最大检测数] - 有效检测数量:形状为
[1]
你需要先记下来这四个输出分别对应你模型的输出索引是多少。
第二步:修复方案二选一即可
方案1:重新导出转换TFLite模型,对齐输出顺序
- 重新调用官方导出脚本导出SavedModel,确保参数正确:
python export_tflite_graph_tf2.py \ --pipeline_config_path=替换为你的pipeline.config路径 \ --trained_checkpoint_dir=替换为训练后的checkpoint存储路径 \ --output_directory=替换为SavedModel输出路径
- 转换为TFLite时指定输出顺序,和插件要求的「检测框→类别→置信度→数量」顺序对齐:
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model( "替换为上一步导出的SavedModel路径", signature_keys=['serving_default'] ) # 这里的输出数组顺序替换为你第一步查到的四个输出的对应索引,顺序为:检测框、类别、置信度、数量 converter.output_arrays = ['StatefulPartitionedCall:0', 'StatefulPartitionedCall:2', 'StatefulPartitionedCall:1', 'StatefulPartitionedCall:3'] # 开启量化和算子支持 converter.optimizations = [tf.lite.Optimize.DEFAULT] converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS, tf.lite.OpsSet.SELECT_TF_OPS] tflite_model = converter.convert() with open("修正后模型.tflite", "wb") as f: f.write(tflite_model)
转换完成后替换项目中原有的模型文件即可。
方案2:修改Flutter tflite插件的解析逻辑,适配现有模型
- 找到项目依赖中tflite插件的
TflitePlugin.java文件,定位到RunSSDMobileNet类的runTflite方法 - 调整方法中输出数组的赋值顺序,和你第一步查到的模型输出顺序对齐即可,比如你模型的检测框在索引1的位置,就把原来给output[0]赋值检测框的逻辑改成给output[1]赋值。
额外注意事项
输入模型的图像需要符合ssd_mobilenet_v2的预处理要求:
- 尺寸缩放到
640x640 - 像素值归一化到
[-1, 1]区间
内容的提问来源于stack exchange,提问作者Sherryl Sugiono Sindarto
相关产品推荐
相关产品推荐

