已训练TensorFlow CNN模型跨.py文件测试时变量未定义的解决方法
解决TensorFlow恢复模型后输入输出张量未定义的问题
这个问题我之前帮好几个开发者踩过坑,核心原因是测试脚本没有正确关联训练时构建的图结构里的输入、输出张量。下面给你几种实用的解决方案,你可以根据自己的代码情况选择:
方法一:完全复用训练时的张量定义
如果你的训练脚本里的输入输出张量定义(比如input_img、output)逻辑不复杂,最简单的方式就是在测试脚本里原封不动地复制训练时的张量定义代码。比如训练时你是这么定义的:
# 训练脚本里的定义 input_img = tf.placeholder(tf.float32, shape=[None, 224, 224, 3], name="input_img") # ... 中间CNN层定义 ... logits = tf.layers.dense(last_layer, units=10) output = tf.nn.softmax(logits, name="output")
那测试脚本里先复制这段定义,然后再加载模型:
import tensorflow as tf import cv2 import numpy as np # 1. 复制训练时的张量定义(必须完全一致,包括shape、名称) input_img = tf.placeholder(tf.float32, shape=[None, 224, 224, 3], name="input_img") # ... 复制训练时的CNN层定义 ... logits = tf.layers.dense(last_layer, units=10) output = tf.nn.softmax(logits, name="output") # 2. 加载模型 checkpoint saver = tf.train.Saver() with tf.Session() as sess: # 加载保存的模型参数 saver.restore(sess, "./path/to/your/model") # 这里不用加.meta,只需要模型前缀名 # 3. 预处理测试图像(必须和训练时的预处理逻辑完全一致!) test_img = cv2.imread("test.jpg") test_img = cv2.resize(test_img, (224, 224)) test_img = test_img / 255.0 # 假设训练时做了归一化 test_img = np.expand_dims(test_img, axis=0) # 增加batch维度 # 4. 运行模型得到结果 pred = sess.run(output, feed_dict={input_img: test_img}) print("预测结果:", np.argmax(pred))
方法二:通过张量名称从加载的图中直接获取
如果你不想复制大量训练代码,可以在训练时给输入输出张量显式命名,然后在测试脚本里加载图结构后,通过名称获取这些张量。
第一步:训练时给张量命名
修改训练脚本,给input_img和output加上明确的name参数:
# 训练脚本里修改定义 input_img = tf.placeholder(tf.float32, shape=[None, 224, 224, 3], name="input_img") # ... 中间CNN层 ... output = tf.nn.softmax(logits, name="model_output") # 给输出张量命名
第二步:测试脚本中加载图并获取张量
import tensorflow as tf import cv2 import numpy as np # 1. 加载.meta文件,导入整个图结构 saver = tf.train.import_meta_graph("./path/to/your/model.meta") graph = tf.get_default_graph() # 2. 通过张量名称获取输入输出节点 # 注意:张量名称后面要加":0",这是TensorFlow的张量索引规则(第一个输出张量的索引是0) input_tensor = graph.get_tensor_by_name("input_img:0") output_tensor = graph.get_tensor_by_name("model_output:0") # 3. 加载模型参数并运行 with tf.Session() as sess: saver.restore(sess, "./path/to/your/model") # 模型前缀名 # 预处理图像(和训练时一致) test_img = cv2.imread("test.jpg") test_img = cv2.resize(test_img, (224, 224)) test_img = test_img / 255.0 test_img = np.expand_dims(test_img, axis=0) # 预测 pred = sess.run(output_tensor, feed_dict={input_tensor: test_img}) print("预测类别:", np.argmax(pred))
关键注意事项
- 预处理必须一致:测试图像的缩放、归一化、通道顺序(比如RGB/BGR)必须和训练时完全相同,否则模型预测结果会完全不可靠。
- 张量名称要准确:如果训练时用了变量作用域(比如
with tf.variable_scope("conv1"):),那获取张量时要加上作用域前缀,比如"conv1/weights:0"。你可以在训练时用print(input_img.name)和print(output.name)输出张量的完整名称,测试时直接用这个名称加:0。 - 模型路径正确:
saver.restore的参数是模型的前缀名(比如你保存的文件是model.ckpt-1000.meta、model.ckpt-1000.index,那路径就是"./model.ckpt-1000")。
内容的提问来源于stack exchange,提问作者Salhi Fedi
相关产品推荐
相关产品推荐

