簡體   English   中英

如何使張量流會話在預測之間保持開放? 從SavedModel加載

[英]How to keep tensorflow session open between predictions? Loading from SavedModel

我訓練了一個張量流模型,我希望對numpy數組進行預測。 這用於視頻中的圖像處理。 我會在圖像發生時將其傳遞給模型。 並非每幀都通過。

我在這樣的會話中重新加載 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?

編輯我嘗試了兩個步驟來創建會話的第一個答案:

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作為變量傳遞給類的第二個想法,這是一個很好的想法。 這有效:

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 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)

其他人已經解釋了為什么不能在構造函數的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()]))

您的代碼創建一個作用域,該作用域在離開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

您的代碼不起作用,因為您在init函數中打開了會話並關閉了會話。 因此,初始化完成后將沒有會話。

如果您想在模型訓練后做出許多預測,建議您不要重新發明輪子,而是使用TF開發人員為此創建的工具: TF服務

TensorFlow Serving是一個針對機器學習模型的靈活,高性能的服務系統,專為生產環境而設計。 使用TensorFlow Serving可以輕松部署新算法和實驗,同時保持相同的服務器體系結構和API。 TensorFlow Serving提供與TensorFlow模型的現成集成,但可以輕松擴展以服務其他類型的模型和數據

他們有很多教程,從最基礎的教程開始,花一天的時間學習一些東西將為您節省數月的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM