Tensorflow负载模型错误
Tenorflow load model error
我正在尝试加载以前保存的 TENSOFLOW 模型(图表和变量)。
这是我在训练期间导出模型的方式
tf.global_variables_initializer().run()
y = tf.matmul(x, W) + b
cross_entropy = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
for batch_index in range(batch_size):
batch_xs, batch_ys = sample_dataframe(train_df, N=batch_size)
#print(batch_xs.shape)
#print(batch_ys.shape)
sess.run(train_step, feed_dict = {x: batch_xs, y_:batch_ys})
if batch_index % 100 == 0:
print("Batch "+str(batch_index))
correct_predictions = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))
print("Accuracy: "+str(sess.run(accuracy,
feed_dict = {x: batch_xs, y_: batch_ys})))
#print("Predictions "+str(y))
#print("Training accuracy: %.1f%%" %accuracy())
if batch_index + 1 == batch_size:
#Save the trained model
print("Exporting trained model")
builder = saved_model_builder.SavedModelBuilder(EXPORT_DIR)
builder.add_meta_graph_and_variables(sess, ['simple-MNIST'])
builder.save(as_text=True)
请忽略模型的定义方式(这只是一个玩具示例),只检查调用保存方法的最后几行。一切顺利,模型已正确保存在 FS 中。
当我尝试加载导出的模型时,我总是收到以下错误:
TypeError: Can not convert a MetaGraphDef into a Tensor or Operation.
这是我加载模型的方式:
with tf.Session() as sess:
print(tf.saved_model.loader.maybe_saved_model_directory(export_dir))
saved_model = tf.saved_model.loader.load(sess, ['simple-MNIST'], export_dir)
sess.run(saved_model)
知道如何解决吗?似乎模型以错误的格式导出,但我不知道如何更改它。
这是一个用于加载模型并对其评分的简单脚本。
with tf.device("/cpu:0"):
x = tf.placeholder(tf.float32, shape =(batch_size, 784))
W = tf.Variable(tf.truncated_normal(shape=(784, 10), stddev=0.1))
b = tf.Variable(tf.zeros([10]))
y_ = tf.placeholder(tf.float32, shape=(batch_size, 10))
with tf.Session() as sess:
tf.global_variables_initializer().run()
print(tf.saved_model.loader.maybe_saved_model_directory(export_dir))
saved_model = tf.saved_model.loader.load(sess, ['simple-MNIST'], export_dir)
batch_xs, batch_ys = sample_dataframe(train_df, N=batch_size)
y = tf.matmul(x, W) + b
correct_predictions = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))
print("Test Accuracy: "+ str(sess.run(accuracy, feed_dict = {x: batch_xs, y_: batch_ys})))
运行 这个脚本在全新的 PYTHON 上下文中,将以非常低的准确性对模型进行评分(似乎加载模型方法没有正确设置图形变量)
谢谢!
我认为问题在于您不能将 saved_model
传递给 sess.run
。来自 saved_model.loader.load
的文档:
Returns:
The MetaGraphDef
protocol buffer loaded in the provided session. This
can be used to further extract signature-defs, collection-defs, etc.
那么,当 saved_model
是 MetaGraphDef
时,您对 sess.run(saved_model)
的期望是什么?如果我正确理解了 load
的机制,那么图表和相关变量将在您传递给 load(..)
的会话中恢复,因此您的模型可以使用一次 load(..)
完成的。因此,您应该能够像往常一样通过(默认)图表访问变量、操作和张量,而无需进一步处理返回的 MetaGraphDef
对象。
这里有更多关于 MetaGraphDef
是什么的信息:。由此应该清楚,将它与 sess.run()
.
一起使用是没有意义的
编辑
跟进您的编辑:函数 tf.saved_model.loader.load
在内部调用 tf.import_meta_graph
,然后调用 saver.restore
,即它恢复了图形 和 图中存在的变量的值。因此,您不必在添加的代码片段的开头自行重新定义变量。事实上,它可能会导致未定义的行为,因为某些节点可能会在默认图中出现两次。检查此 Whosebug post 以获取更多信息:Restoring Tensorflow model and viewing variable value。所以我想这里发生的事情是:推理步骤使用您手动创建的未经训练的变量 W
,而不是您通过 saved_model.loader
加载的预训练变量,这就是为什么您会看到准确度低的原因。
所以,我的猜测是,如果你在开始时省略 x
、W
、b
和 y_
的定义,并从恢复的图中检索它们例如通过调用 tf.get_default_graph().get_tensor_by_name('variable_name'))
它应该可以正常工作。
PS:如果您正在恢复模型,则不需要 运行 初始化器(即使我认为它也不会造成伤害)。
PPS:在您的脚本中,您正在计算准确度 'by hand',但我假设该操作已经存在于模型中,因为它很可能在训练期间也需要,不?因此,无需再次手动计算准确度,您只需从图中获取相应的节点并使用它即可。
我正在尝试加载以前保存的 TENSOFLOW 模型(图表和变量)。
这是我在训练期间导出模型的方式
tf.global_variables_initializer().run()
y = tf.matmul(x, W) + b
cross_entropy = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
for batch_index in range(batch_size):
batch_xs, batch_ys = sample_dataframe(train_df, N=batch_size)
#print(batch_xs.shape)
#print(batch_ys.shape)
sess.run(train_step, feed_dict = {x: batch_xs, y_:batch_ys})
if batch_index % 100 == 0:
print("Batch "+str(batch_index))
correct_predictions = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))
print("Accuracy: "+str(sess.run(accuracy,
feed_dict = {x: batch_xs, y_: batch_ys})))
#print("Predictions "+str(y))
#print("Training accuracy: %.1f%%" %accuracy())
if batch_index + 1 == batch_size:
#Save the trained model
print("Exporting trained model")
builder = saved_model_builder.SavedModelBuilder(EXPORT_DIR)
builder.add_meta_graph_and_variables(sess, ['simple-MNIST'])
builder.save(as_text=True)
请忽略模型的定义方式(这只是一个玩具示例),只检查调用保存方法的最后几行。一切顺利,模型已正确保存在 FS 中。
当我尝试加载导出的模型时,我总是收到以下错误:
TypeError: Can not convert a MetaGraphDef into a Tensor or Operation.
这是我加载模型的方式:
with tf.Session() as sess:
print(tf.saved_model.loader.maybe_saved_model_directory(export_dir))
saved_model = tf.saved_model.loader.load(sess, ['simple-MNIST'], export_dir)
sess.run(saved_model)
知道如何解决吗?似乎模型以错误的格式导出,但我不知道如何更改它。
这是一个用于加载模型并对其评分的简单脚本。
with tf.device("/cpu:0"):
x = tf.placeholder(tf.float32, shape =(batch_size, 784))
W = tf.Variable(tf.truncated_normal(shape=(784, 10), stddev=0.1))
b = tf.Variable(tf.zeros([10]))
y_ = tf.placeholder(tf.float32, shape=(batch_size, 10))
with tf.Session() as sess:
tf.global_variables_initializer().run()
print(tf.saved_model.loader.maybe_saved_model_directory(export_dir))
saved_model = tf.saved_model.loader.load(sess, ['simple-MNIST'], export_dir)
batch_xs, batch_ys = sample_dataframe(train_df, N=batch_size)
y = tf.matmul(x, W) + b
correct_predictions = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))
print("Test Accuracy: "+ str(sess.run(accuracy, feed_dict = {x: batch_xs, y_: batch_ys})))
运行 这个脚本在全新的 PYTHON 上下文中,将以非常低的准确性对模型进行评分(似乎加载模型方法没有正确设置图形变量)
谢谢!
我认为问题在于您不能将 saved_model
传递给 sess.run
。来自 saved_model.loader.load
的文档:
Returns: The
MetaGraphDef
protocol buffer loaded in the provided session. This can be used to further extract signature-defs, collection-defs, etc.
那么,当 saved_model
是 MetaGraphDef
时,您对 sess.run(saved_model)
的期望是什么?如果我正确理解了 load
的机制,那么图表和相关变量将在您传递给 load(..)
的会话中恢复,因此您的模型可以使用一次 load(..)
完成的。因此,您应该能够像往常一样通过(默认)图表访问变量、操作和张量,而无需进一步处理返回的 MetaGraphDef
对象。
这里有更多关于 MetaGraphDef
是什么的信息:sess.run()
.
编辑
跟进您的编辑:函数 tf.saved_model.loader.load
在内部调用 tf.import_meta_graph
,然后调用 saver.restore
,即它恢复了图形 和 图中存在的变量的值。因此,您不必在添加的代码片段的开头自行重新定义变量。事实上,它可能会导致未定义的行为,因为某些节点可能会在默认图中出现两次。检查此 Whosebug post 以获取更多信息:Restoring Tensorflow model and viewing variable value。所以我想这里发生的事情是:推理步骤使用您手动创建的未经训练的变量 W
,而不是您通过 saved_model.loader
加载的预训练变量,这就是为什么您会看到准确度低的原因。
所以,我的猜测是,如果你在开始时省略 x
、W
、b
和 y_
的定义,并从恢复的图中检索它们例如通过调用 tf.get_default_graph().get_tensor_by_name('variable_name'))
它应该可以正常工作。
PS:如果您正在恢复模型,则不需要 运行 初始化器(即使我认为它也不会造成伤害)。
PPS:在您的脚本中,您正在计算准确度 'by hand',但我假设该操作已经存在于模型中,因为它很可能在训练期间也需要,不?因此,无需再次手动计算准确度,您只需从图中获取相应的节点并使用它即可。