tensorflow 2.0:正在传递函数构建代码之外的操作
tensorflow 2.0: An op outside of the function building code is being passed
我收到一个错误:
TypeError: An op outside of the function building code is being passed
a "Graph" tensor. It is possible to have Graph tensors
leak out of the function building context by including a
tf.init_scope in your function building code.
For example, the following function will fail:
@tf.function
def has_init_scope():
my_constant = tf.constant(1.)
with tf.init_scope():
added = my_constant * 2
使用如下的 NVP 层:
import tensorflow_probability as tfp
tfb = tfp.bijectors
tfd = tfp.distributions
class NVPLayer(tf.keras.models.Model):
def __init__(self, *, output_dim, num_masked, **kwargs):
super().__init__(**kwargs)
self.output_dim = output_dim
self.num_masked = num_masked
self.shift_and_log_scale_fn = tfb.real_nvp_default_template(
hidden_layers=[2], # HERE HERE ADJUST THIS
activation=None, # linear
)
self.loss = None
def get_nvp(self):
nvp = tfd.TransformedDistribution(
distribution=tfd.MultivariateNormalDiag(loc=[0.] * self.output_dim),
bijector=tfb.RealNVP(
num_masked=self.num_masked,
shift_and_log_scale_fn=self.shift_and_log_scale_fn)
)
return nvp
def call(self, *inputs):
nvp = self.get_nvp()
self.loss = tf.reduce_mean(nvp.log_prob(*inputs)) # how else to do this?
# return nvp.bijector.forward(*inputs)
return nvp.bijector.inverse(*inputs)
我不会在任何地方打电话给 tf.init_scope
。训练类似层的简单版本似乎有效。
我会尝试获得更细粒度的跟踪,但我怀疑这与非热切模式有关。
更新: 所以这肯定来自 self.loss
包含在某些渐变带层中。正确的做法是什么?
UPDATE: so this is definitely coming from the self.loss inclusion in some gradient tape layer. What is the correct way of doing this?
我认为正确的做法是
self.add_loss(<your loss tensor>)
(https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer#add_loss 了解更多)
(编辑抱歉,我没有注意你的 post 的日期,所以我想这已经不是很有用了哈哈)
几分钟前刚遇到同样的问题,在我的例子中,我想修改损失函数中的状态 class,这是我在你的例子中的解决方法。
顺便说一句
@simon 给了我如何正确评估这一点的灵感。所以支持他!
您似乎应该为训练时要更改的属性创建一个 tf.Variable
。请注意,其他属性(例如 self.output_dim
、self.num_masked
和其他
没有任何问题
试试这个:
import tensorflow_probability as tfp
tfb = tfp.bijectors
tfd = tfp.distributions
class NVPLayer(tf.keras.models.Model):
def __init__(self, *, output_dim, num_masked, **kwargs):
super().__init__(**kwargs)
self.output_dim = output_dim
self.num_masked = num_masked
self.shift_and_log_scale_fn = tfb.real_nvp_default_template(
hidden_layers=[2], # HERE HERE ADJUST THIS
activation=None, # linear
)
###CHANGE HERE
self.loss = tf.Variable(0.0)
def get_nvp(self):
nvp = tfd.TransformedDistribution(
distribution=tfd.MultivariateNormalDiag(loc=[0.] * self.output_dim),
bijector=tfb.RealNVP(
num_masked=self.num_masked,
shift_and_log_scale_fn=self.shift_and_log_scale_fn)
)
return nvp
def call(self, *inputs):
nvp = self.get_nvp()
### CHANGE HERE
self.loss.assign(tf.reduce_mean(nvp.log_prob(*inputs)))
# return nvp.bijector.forward(*inputs)
return nvp.bijector.inverse(*inputs)
在 github 问题上也查看这个 answer,类似的问题!
我收到一个错误:
TypeError: An op outside of the function building code is being passed
a "Graph" tensor. It is possible to have Graph tensors
leak out of the function building context by including a
tf.init_scope in your function building code.
For example, the following function will fail:
@tf.function
def has_init_scope():
my_constant = tf.constant(1.)
with tf.init_scope():
added = my_constant * 2
使用如下的 NVP 层:
import tensorflow_probability as tfp
tfb = tfp.bijectors
tfd = tfp.distributions
class NVPLayer(tf.keras.models.Model):
def __init__(self, *, output_dim, num_masked, **kwargs):
super().__init__(**kwargs)
self.output_dim = output_dim
self.num_masked = num_masked
self.shift_and_log_scale_fn = tfb.real_nvp_default_template(
hidden_layers=[2], # HERE HERE ADJUST THIS
activation=None, # linear
)
self.loss = None
def get_nvp(self):
nvp = tfd.TransformedDistribution(
distribution=tfd.MultivariateNormalDiag(loc=[0.] * self.output_dim),
bijector=tfb.RealNVP(
num_masked=self.num_masked,
shift_and_log_scale_fn=self.shift_and_log_scale_fn)
)
return nvp
def call(self, *inputs):
nvp = self.get_nvp()
self.loss = tf.reduce_mean(nvp.log_prob(*inputs)) # how else to do this?
# return nvp.bijector.forward(*inputs)
return nvp.bijector.inverse(*inputs)
我不会在任何地方打电话给 tf.init_scope
。训练类似层的简单版本似乎有效。
我会尝试获得更细粒度的跟踪,但我怀疑这与非热切模式有关。
更新: 所以这肯定来自 self.loss
包含在某些渐变带层中。正确的做法是什么?
UPDATE: so this is definitely coming from the self.loss inclusion in some gradient tape layer. What is the correct way of doing this?
我认为正确的做法是
self.add_loss(<your loss tensor>)
(https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer#add_loss 了解更多)
(编辑抱歉,我没有注意你的 post 的日期,所以我想这已经不是很有用了哈哈)
几分钟前刚遇到同样的问题,在我的例子中,我想修改损失函数中的状态 class,这是我在你的例子中的解决方法。
顺便说一句 @simon 给了我如何正确评估这一点的灵感。所以支持他!
您似乎应该为训练时要更改的属性创建一个 tf.Variable
。请注意,其他属性(例如 self.output_dim
、self.num_masked
和其他
试试这个:
import tensorflow_probability as tfp
tfb = tfp.bijectors
tfd = tfp.distributions
class NVPLayer(tf.keras.models.Model):
def __init__(self, *, output_dim, num_masked, **kwargs):
super().__init__(**kwargs)
self.output_dim = output_dim
self.num_masked = num_masked
self.shift_and_log_scale_fn = tfb.real_nvp_default_template(
hidden_layers=[2], # HERE HERE ADJUST THIS
activation=None, # linear
)
###CHANGE HERE
self.loss = tf.Variable(0.0)
def get_nvp(self):
nvp = tfd.TransformedDistribution(
distribution=tfd.MultivariateNormalDiag(loc=[0.] * self.output_dim),
bijector=tfb.RealNVP(
num_masked=self.num_masked,
shift_and_log_scale_fn=self.shift_and_log_scale_fn)
)
return nvp
def call(self, *inputs):
nvp = self.get_nvp()
### CHANGE HERE
self.loss.assign(tf.reduce_mean(nvp.log_prob(*inputs)))
# return nvp.bijector.forward(*inputs)
return nvp.bijector.inverse(*inputs)
在 github 问题上也查看这个 answer,类似的问题!