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