我训练了一个张量流模型,我想从numpy数组中运行预测。这适用于视频中的图像处理。我会将图像传递给模型。并非每一帧都通过。
I reload我的SavedModel在会话中如此
def run(self):
with tf.Session(graph=tf.Graph()) as sess:
tf.saved_model.loader.load(sess,
[tf.saved_model.tag_constants.SERVING], "model")
如果我将图像列表(self.tfimages)传递给预测,我的代码就能完美运行。简而言之:
softmax_tensor = sess.graph.get_tensor_by_name('final_ops/softmax:0')
predictions = sess.run(softmax_tensor, {'Placeholder:0': self.tfimages})
但我不会立刻拥有所有图像。我是否真的必须每次从文件重新加载模型(需要2分钟以上)。
我想做这样的事情
class tensorflow_model:
def __init__(self):
with tf.Session(graph=tf.Graph()) as self.sess:
tf.saved_model.loader.load(self.sess,
[tf.saved_model.tag_constants.SERVING], "model")
def predict(self):
# Feed the image_data as input to the graph and get first prediction
softmax_tensor = self.sess.graph.get_tensor_by_name('final_ops/softmax:0')
predictions = self.sess.run(softmax_tensor, {'Placeholder:0': self.tfimages})
但是产生了
builtins.RuntimeError:尝试使用已关闭的会话
有没有办法让会话保持打开状态,或者可能独立于会话加载SavedModel?
EDIT 我尝试了第一个答案,分两步创建一个会话:
sess=tf.Session(graph=tf.Graph())
sess
<tensorflow.python.client.session.Session object at 0x0000021ACBB62EF0>
tf.saved_model.loader.load(sess,[tf.saved_model.tag_constants.SERVING], "model")
Traceback (most recent call last):
Debug Probe, prompt 138, line 1
File "C:\Program Files\Python35\Lib\site-packages\tensorflow\python\saved_model\loader_impl.py", line 222, in load
saver.restore(sess, variables_path)
File "C:\Program Files\Python35\Lib\site-packages\tensorflow\python\training\saver.py", line 1428, in restore
{self.saver_def.filename_tensor_name: save_path})
File "C:\Program Files\Python35\Lib\site-packages\tensorflow\python\client\session.py", line 774, in run
run_metadata_ptr)
File "C:\Program Files\Python35\Lib\site-packages\tensorflow\python\client\session.py", line 905, in _run
raise RuntimeError('The Session graph is empty. Add operations to the '
builtins.RuntimeError: The Session graph is empty. Add operations to the graph before calling run().
而
with tf.Session(graph=tf.Graph()) as sess:
tf.saved_model.loader.load(sess,[tf.saved_model.tag_constants.SERVING], "model")
执行无误。
关于将sess作为变量传递给class的第二个想法,这是一个很好的。这有效:
with tf.Session(graph=tf.Graph()) as sess:
tf.saved_model.loader.load(sess,[tf.saved_model.tag_constants.SERVING], "model")
tensorflow_instance=tensorflow(read_from="file")
tensorflow_instance.predict(sess)
但这不是
sess=tf.Session(graph=tf.Graph())
tf.saved_model.loader.load(sess,[tf.saved_model.tag_constants.SERVING], "model")
tensorflow_instance=tensorflow(read_from="file")
tensorflow_instance.predict(sess)
将我的程序包装到with as sess语句中会非常尴尬。
完整代码:
import tensorflow as tf
import sys
from google.protobuf import text_format
from tensorflow.core.framework import graph_pb2
import os
import glob
class tensorflow:
def __init__(self,read_from):
#frames to be analyzed
self.tfimages=[]
find_photos=glob.glob("*.jpg")
# Read in the image_data
if read_from=="file":
for x in find_photos:
image_data = tf.gfile.FastGFile(x, 'rb').read()
self.tfimages.append(image_data)
# Loads label file, strips off carriage return
self.label_lines = [line.rstrip() for line in tf.gfile.GFile("dict.txt")]
def predict(self,sess):
# Feed the image_data as input to the graph and get first prediction
softmax_tensor = sess.graph.get_tensor_by_name('final_ops/softmax:0')
predictions = sess.run(softmax_tensor, {'Placeholder:0': self.tfimages})
for prediction in predictions:
# Sort to show labels of first prediction in order of confidence
top_k = prediction.argsort()[-len(prediction):][::-1]
for node_id in top_k:
human_string = self.label_lines[node_id]
score = prediction[node_id]
print('%s (score = %.5f)' % (human_string, score))
return(human_string)
if __name__ == "__main__":
with tf.Session(graph=tf.Graph()) as sess:
tf.saved_model.loader.load(sess,[tf.saved_model.tag_constants.SERVING], "model")
tensorflow_instance=tensorflow(read_from="file")
tensorflow_instance.predict(sess)
sess=tf.Session(graph=tf.Graph())
tf.saved_model.loader.load(sess,[tf.saved_model.tag_constants.SERVING], "model")
tensorflow_instance=tensorflow(read_from="file")
tensorflow_instance.predict(sess)
答案 0 :(得分:7)
其他人已经解释了为什么你不能把你的会话放在构造函数的with
语句中。
您在使用上下文管理器时看到不同行为的原因是因为tf.saved_model.loader.load
在默认图表和作为会话一部分的图表之间存在一些奇怪的交互。
解决方案很简单;如果你没有在with
块中使用它,请不要将图表传递给会话:
sess=tf.Session()
tf.saved_model.loader.load(sess,[tf.saved_model.tag_constants.SERVING], "model")
这是一个用于预测的类的示例代码:
class Model(object):
def __init__(self, model_path):
# Note, if you don't want to leak this, you'll want to turn Model into
# a context manager. In practice, you probably don't have to worry
# about it.
self.session = tf.Session()
tf.saved_model.loader.load(
self.session,
[tf.saved_model.tag_constants.SERVING],
model_path)
self.softmax_tensor = self.session.graph.get_tensor_by_name('final_ops/softmax:0')
def predict(self, images):
predictions = self.session.run(self.softmax, {'Placeholder:0': images})
# TODO: convert to human-friendly labels
return predictions
images = [tf.gfile.FastGFile(f, 'rb').read() for f in glob.glob("*.jpg")]
model = Model('model_path')
print(model.predict(images))
# Alternatively (uses less memory, but has lower throughput):
for f in glob.glob("*.jpg"):
print(model.predict([tf.gfile.FastGFile(f, 'rb').read()]))
答案 1 :(得分:0)
您的代码创建了一个在离开init后退出的范围。
def __init__(self):
with tf.Session(graph=tf.Graph()) as self.sess:
tf.saved_model.loader.load(self.sess[tf.saved_model.tag_constants.SERVING], "model")
如果其他一切正常工作,以下内容应该适合您。
def __init__(self):
self.sess=tf.Session(graph=tf.Graph())
tf.saved_model.loader.load(self.sess[tf.saved_model.tag_constants.SERVING], "model")
当我做这样的事情时,我通常也会创建一个通过参数将会话传递给类的选项,然后当我调用类时,我传递了with
创建的会话
答案 2 :(得分:0)
您的代码不起作用,因为在您的init函数中,您打开会话并关闭它。所以在init完成后没有会话。
如果您想在模型训练后做出许多预测,我建议您不要重新发明轮子并使用工具,TF开发人员为此创建了这个工具:TF serving。
TensorFlow Serving是一种灵活的高性能服务系统 机器学习模型,专为生产环境而设计。 TensorFlow服务可以轻松部署新算法和 实验,同时保持相同的服务器架构和API。 TensorFlow Serving提供与TensorFlow的开箱即用集成 模型,但可以很容易地扩展到其他类型的模型和 数据
他们从very basic ones开始有很多教程,花一天时间学习一些东西会在几个月后为你节省。