OpenCV调用readNetFromTensorflow报DT_VARIANT未知枚举错误如何解决
问题原因
你导出冻结模型时错误将所有训练阶段的全局变量加入了输出节点列表,其中包含OpenCV DNN模块不支持的DT_VARIANT类型变量(这类变量仅用于TensorFlow训练过程,推理阶段完全不需要)。你代码中freeze_session函数内的output_names += [v.op.name for v in tf.global_variables()]是产生冗余节点的直接原因。
解决方案
按以下步骤修改导出逻辑即可:
1. 移除冗余节点导出逻辑
删除freeze_session函数中如下代码行:
output_names += [v.op.name for v in tf.global_variables()]
仅保留推理需要的输出节点,不需要将所有全局变量加入输出列表。
2. 调整冻结图调用参数
调用freeze_session时直接传入你自定义的输出节点名,替换原有的output_names=[out.op.name for out in model.outputs]:
frozen_graph = freeze_session(tf.keras.backend.get_session(), output_names=pred_node_names)
3. 裁剪训练相关节点
冻结完成后对计算图做裁剪,移除所有训练阶段的冗余节点:
# 新增代码,放在freeze_session调用之后,write_graph之前 frozen_graph = tf.graph_util.remove_training_nodes(frozen_graph)
4. 调整OpenCV加载逻辑
OpenCV的readNetFromTensorflow可以直接读取二进制PB文件,不需要额外传入PBTXT文件,避免文本格式解析兼容问题:
tensorflowNet = cv2.dnn.readNetFromTensorflow('xor.pb')
额外注意事项
- 尽量使用TensorFlow内置的
tf.keras层定义,不要混用独立安装的Keras包,避免层实现不一致导出多余节点 - 导出前可以检查pbtxt文件,确认没有
DT_VARIANT相关字段后再用OpenCV加载
内容的提问来源于stack exchange,提问作者230490
相关产品推荐
相关产品推荐

