Tenorflow负载模型错误

时间:2017-04-04 10:02:29

标签: python tensorflow tensorflow-serving

我正在尝试加载以前保存的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)

请忽略模型的定义方式(这只是一个玩具示例),并仅检查调用save方法的最后几行。一切都很顺利,模型正确保存在FS中。

当我尝试加载导出的模型时,我总是会收到以下错误:

  

TypeError:无法将MetaGraphDef转换为Tensor或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上下文中运行此脚本,将以非常低的精度对模型进行评分(似乎负载模型方法未正确设置图形变量)

谢谢!

1 个答案:

答案 0 :(得分:2)

我认为问题在于您无法将saved_model传递给sess.run。来自saved_model.loader.load的文档:

  

返回:       在提供的会话中加载MetaGraphDef协议缓冲区。这个       可用于进一步提取签名定义,收集定义等。

那么,当sess.run(saved_model)saved_model时,您对MetaGraphDef的期望是什么?如果我已正确理解load的机制,那么图表以及相关变量将在您传递给load(..)的会话中恢复,因此您的模型可以使用一次{{1}完了。因此,您应该像往常一样通过(默认)图访问变量,操作和张量,并且无需进一步处理返回的load(..)对象。

以下是有关MetaGraphDef的详细信息:What is the TensorFlow checkpoint meta file?。从这一点可以清楚地看出,将它与MetaGraphDef一起使用是没有意义的。

修改

跟进您的修改:功能sess.run()在内部调用tf.saved_model.loader.load后跟tf.import_meta_graph,即它还会恢复图形变量的值出现在图表中。因此,您不必在自己添加的代码段的开头重新定义变量。实际上,它可能会导致未定义的行为,因为某些节点可能在默认图中存在两次。请查看此stackoverflow帖子以获取更多信息:Restoring Tensorflow model and viewing variable value。所以我猜这里发生的事情是:推理步骤使用您手动创建的未经训练的变量saver.restore,而不是通过W加载的预训练变量saved_model.loader,这就是您看到低精度的原因。< / p>

所以,我的猜测是,如果您在开头省略xWby_的定义,并从恢复的图表中检索它们,例如通过调用tf.get_default_graph().get_tensor_by_name('variable_name'))它应该可以正常工作。

PS:如果要恢复模型,则无需运行初始化程序(即使我认为它也没有损坏)。

PPS:在您的脚本中,您正在“手动”计算准确度,但我会假设此操作已经存在于模型中,因为在训练期间最有可能需要,不是吗?因此,您无需再次从手中计算精度,只需从图中获取相应的节点并使用它。