Understanding `TypeError: An op outside of the function building code is being passed a "Graph" tensor.` error
Understanding `TypeError: An op outside of the function building code is being passed a "Graph" tensor.` error
我在自定义实验框架中使用 TF2.4,并使用 mlworkflow.lazyproperty
装饰器在第一次访问时构造属性(如 tf.keras.Model()
)。
对于我的大部分深度学习实验,此框架运行良好,但我在实验中尝试另一个头时遇到 TypeError: An op outside of the function building code is being passed a "Graph" tensor.
错误。
我设法将问题简化为以下最小工作示例,其中在使用我的自定义对象 Head_1()
时出现错误,但在使用 Head_2(tf.keras.layers.Layer)
时它工作正常。
import numpy as np
from mlworkflow import lazyproperty
class Head_1():
def __call__(self, inputs):
return tf.ones((20,25))[tf.newaxis] + inputs[...,0]
class Head_2(tf.keras.layers.Layer):
def call(self, inputs):
return tf.ones((20,25))[tf.newaxis] + inputs[...,0]
class Experiment():
@lazyproperty
def model(self):
inputs = tf.keras.Input(dtype=tf.float32, shape=(20, 25, 3))
model = tf.keras.layers.Conv2D(5, 1)
head = Head_1()
logits = model(inputs)
outputs = head(logits)
return tf.keras.Model(inputs, outputs)
@tf.function
def run(self, data):
return self.model(data, training=True)
exp = Experiment()
exp.run(np.ones((1, 20, 25, 3), dtype=np.float32))
有人可以解释为什么 Head_1
将 «_"Graph" 张量_» 传递给函数构建代码_» 之外的 «_op,而 Head_2
不这样做吗?
我不能使用 Head_2
,因为我需要我的自定义对象来控制 __call__
方法中发生的事情。
解决方案是在调用 run
之前创建模型。具体
exp = Experiment()
_ = exp.model # creates model before first call of the tf.function
exp.run(np.ones((1, 20, 25, 3), dtype=np.float32))
我在自定义实验框架中使用 TF2.4,并使用 mlworkflow.lazyproperty
装饰器在第一次访问时构造属性(如 tf.keras.Model()
)。
对于我的大部分深度学习实验,此框架运行良好,但我在实验中尝试另一个头时遇到 TypeError: An op outside of the function building code is being passed a "Graph" tensor.
错误。
我设法将问题简化为以下最小工作示例,其中在使用我的自定义对象 Head_1()
时出现错误,但在使用 Head_2(tf.keras.layers.Layer)
时它工作正常。
import numpy as np
from mlworkflow import lazyproperty
class Head_1():
def __call__(self, inputs):
return tf.ones((20,25))[tf.newaxis] + inputs[...,0]
class Head_2(tf.keras.layers.Layer):
def call(self, inputs):
return tf.ones((20,25))[tf.newaxis] + inputs[...,0]
class Experiment():
@lazyproperty
def model(self):
inputs = tf.keras.Input(dtype=tf.float32, shape=(20, 25, 3))
model = tf.keras.layers.Conv2D(5, 1)
head = Head_1()
logits = model(inputs)
outputs = head(logits)
return tf.keras.Model(inputs, outputs)
@tf.function
def run(self, data):
return self.model(data, training=True)
exp = Experiment()
exp.run(np.ones((1, 20, 25, 3), dtype=np.float32))
有人可以解释为什么 Head_1
将 «_"Graph" 张量_» 传递给函数构建代码_» 之外的 «_op,而 Head_2
不这样做吗?
我不能使用 Head_2
,因为我需要我的自定义对象来控制 __call__
方法中发生的事情。
解决方案是在调用 run
之前创建模型。具体
exp = Experiment()
_ = exp.model # creates model before first call of the tf.function
exp.run(np.ones((1, 20, 25, 3), dtype=np.float32))