Python Tensorflow如何管理图形?

Python Tensorflow如何管理图形?,python,tensorflow,loading,encapsulation,prediction,Python,Tensorflow,Loading,Encapsulation,Prediction,我已经意识到,Tensorflow管理图形的方式似乎有些古怪 由于构建(和重建)模型非常繁琐,我决定将自定义模型封装在一个类中,以便在其他地方轻松地重新实例化它 当我训练和测试代码(在初始位置)时,它会工作得很好,但是在加载图形变量的代码中,我会遇到各种奇怪的错误——变量重新定义和其他一切。这(来自我上一个关于类似事情的问题)暗示着所有东西都被调用了两次 在做了大量的跟踪之后,问题归结为我使用加载代码的方式。它是在一个类中使用的,这个类的结构是这样的 class MyModelUser(obje

我已经意识到,Tensorflow管理图形的方式似乎有些古怪

由于构建(和重建)模型非常繁琐,我决定将自定义模型封装在一个类中,以便在其他地方轻松地重新实例化它

当我训练和测试代码(在初始位置)时,它会工作得很好,但是在加载图形变量的代码中,我会遇到各种奇怪的错误——变量重新定义和其他一切。这(来自我上一个关于类似事情的问题)暗示着所有东西都被调用了两次

在做了大量的跟踪之后,问题归结为我使用加载代码的方式。它是在一个类中使用的,这个类的结构是这样的

class MyModelUser(object):
    def forecast(self):
       # .. build the model in the same way as in the training code
       # load the model checkpoint
       # call the "predict" function on the model
       # manipulate the prediction and return it
然后在一些使用
MyModelUser
的代码中

def test_the_model(self):
   model_user = MyModelUser()
   print(model_user.forecast())  # 1
   print(model_user.forecast())  # 2
我(很明显)希望在这一会议上看到两个预测。相反,第一个forecast被调用并按预期工作,但第二个调用抛出了大量变量重用值错误,其中一个示例是:

ValueError: Variable weight_def/weights already exists, disallowed. Did you mean to set reuse=True in VarScope?
我通过添加一系列使用
get\u variable
创建变量的try/except块,然后在异常情况下,在作用域上调用
reuse\u variables
,然后在没有名称的情况下添加
get\u variable
来消除错误。这带来了一系列新的严重错误,其中之一是:

tensorflow.python.framework.errors.NotFoundError: Tensor name "weight_def/weights/Adam_1" not found in checkpoint files
一时兴起,我说:“如果我将建模建筑代码移动到
\uuuu init\uuuu
,那么它只构建一次呢?”

我的新型号用户:

class MyModelUser(object):
    def __init__(self):
       # ... build the model in the same way as in the training code
       # load the model checkpoint


    def forecast(self):
       # call the "predict" function on the model
       # manipulate the prediction and return it
现在:

def test_the_model(self):
   model_user = MyModelUser()
   print(model_user.forecast())  # 1
   print(model_user.forecast())  # 2
按预期工作,打印两个预测没有错误。这让我相信我也可以摆脱可变重用的东西

我的问题是:


为什么要这样做?从理论上讲,在原始预测方法中,每次都应重新插入图形,因此不应创建多个图形。Tensorflow是否在函数完成后仍保持图形?这就是为什么将创建代码移动到
\uuuuu init\uuuu
有效的原因吗?这让我感到无可救药的困惑。

TF有一个默认图,可以添加新的操作等。当您两次调用函数时,您将在同一个图形中添加两次相同的内容。因此,要么构建一次图形,然后对其进行多次评估(正如您所做的,这也是“正常”方法),要么,如果您想更改内容,可以使用reset\u default\u graph重置图形,以获得新的状态。

默认情况下,TensorFlow使用第一次调用TensorFlow API时创建的单个全局实例。如果不显式创建
tf.Graph
,所有操作、张量和变量都将在该默认实例中创建。这意味着每次在代码中调用
model\u user.forecast()
都会将操作添加到同一个全局图中,这有点浪费

这里(至少)有两种可能的行动方案:

  • 理想的操作是重新构造代码,以便
    MyModelUser.\uuu init\uuu()
    构造一个完整的
    tf.Graph
    ,其中包含执行预测所需的所有操作,
    MyModelUser.forecast()
    只需对现有图形执行
    sess.run()
    调用。理想情况下,您也只需要创建一个
    tf.Session
    ,因为TensorFlow会在会话中缓存有关图形的信息,执行效率会更高

  • MyModelUser.forecast()
    的每次调用都创建一个新的
    tf.Graph
    ,这是一个侵入性较小但可能效率较低的更改。在
    MyModelUser.\uuu init\uuuu()
    方法中创建了多少状态,这一问题并不清楚,但您可以执行以下操作,将这两个调用放在不同的图中:

    def test_the_model(self):
      with tf.Graph():  # Create a local graph
        model_user_1 = MyModelUser()
        print(model_user_1.forecast())
      with tf.Graph():  # Create another local graph
        model_user_2 = MyModelUser()
        print(model_user_2.forecast())