OperatorNotAllowedInGraphError 仍然存在,启用了急切执行并添加了装饰器
OperatorNotAllowedInGraphError still there with eager execution enabled and decorator added
我正在努力在 tensorflow 中重现一个简单的代码。
我有自己定义的函数用作我的模型的指标。
这是一个简单的三元组损失函数(稍作修改),但如果我使用普通的损失函数,问题仍然是一样的。
import pandas as pd
import numpy as np
import tensorflow as tf
from tensorflow.keras.activations import sigmoid
from tensorflow.keras import backend
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.layers import Input, Embedding, Flatten, Dense, Dropout, Lambda, dot, concatenate
@tf.function
def bpr_triplet_loss(inputs):
anchor_latent, positive_item_latent, negative_item_latent = inputs
# BPR loss
loss = 1.0 - backend.sigmoid(
backend.sum(anchor_latent * positive_item_latent, axis=-1, keepdims=True) -
backend.sum(anchor_latent * negative_item_latent, axis=-1, keepdims=True))
return loss
def getModel(n_users, n_items, emb_dim = 20):
# Input Layers
user_input = Input(shape=[1], name = 'user_input')
pos_item_input = Input(shape=[1], name = 'pos_item_input')
neg_item_input = Input(shape=[1], name = 'neg_item_input')
# Embedding Layers
# Shared embedding layer for positive and negative items
user_embedding = Embedding(output_dim=emb_dim, input_dim=n_users + 1, input_length=1, name='user_emb')(user_input)
item_embedding = Embedding(output_dim=emb_dim, input_dim=n_items + 1, input_length=1, name='item_emb')
pos_item_embedding = item_embedding(pos_item_input)
neg_item_embedding = item_embedding(neg_item_input)
user_vecs = Flatten()(user_embedding)
pos_item_vecs = Flatten()(pos_item_embedding)
neg_item_vecs = Flatten()(neg_item_embedding)
# Triplet loss function
output = concatenate([user_vecs, pos_item_vecs, neg_item_vecs])
loss = Lambda(bpr_triplet_loss, (1,))(output)
model = Model(inputs=[anchor, positive, negative], outputs=loss)
model.compile(optimizer='Adam', loss='mse',
metrics=["mae"])
# Define and Compile Model
#model = Model(inputs = [user_input, pos_item_input, neg_item_input], outputs = output)
#model.compile(optimizer='Adam', loss=bpr_triplet_loss, metrics=[bpr_triplet_loss])
return model
model = getModel(n_users, n_items) # 6706, 3040
当我 运行 这段代码时,我得到以下(开始令人沮丧的)错误
---------------------------------------------------------------------------
OperatorNotAllowedInGraphError Traceback (most recent call last)
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/base_layer.py in __call__(self, inputs, *args, **kwargs)
841 with auto_control_deps.AutomaticControlDependencies() as acd:
--> 842 outputs = call_fn(cast_inputs, *args, **kwargs)
843 # Wrap Tensors in `outputs` in `tf.identity` to avoid
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/keras/layers/core.py in call(self, inputs, mask, training)
794 with variable_scope.variable_creator_scope(self._variable_creator):
--> 795 return self.function(inputs, **arguments)
796
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py in __call__(self, *args, **kwds)
456 tracing_count = self._get_tracing_count()
--> 457 result = self._call(*args, **kwds)
458 if tracing_count == self._get_tracing_count():
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py in _call(self, *args, **kwds)
502 initializer_map = object_identity.ObjectIdentityDictionary()
--> 503 self._initialize(args, kwds, add_initializers_to=initializer_map)
504 finally:
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py in _initialize(self, args, kwds, add_initializers_to)
407 self._stateful_fn._get_concrete_function_internal_garbage_collected( # pylint: disable=protected-access
--> 408 *args, **kwds))
409
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py in _get_concrete_function_internal_garbage_collected(self, *args, **kwargs)
1847 args, kwargs = None, None
-> 1848 graph_function, _, _ = self._maybe_define_function(args, kwargs)
1849 return graph_function
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py in _maybe_define_function(self, args, kwargs)
2149 if graph_function is None:
-> 2150 graph_function = self._create_graph_function(args, kwargs)
2151 self._function_cache.primary[cache_key] = graph_function
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py in _create_graph_function(self, args, kwargs, override_flat_arg_shapes)
2040 override_flat_arg_shapes=override_flat_arg_shapes,
-> 2041 capture_by_value=self._capture_by_value),
2042 self._function_attributes,
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/func_graph.py in func_graph_from_py_func(name, python_func, args, kwargs, signature, func_graph, autograph, autograph_options, add_control_dependencies, arg_names, op_return_value, collections, capture_by_value, override_flat_arg_shapes)
914
--> 915 func_outputs = python_func(*func_args, **func_kwargs)
916
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py in wrapped_fn(*args, **kwds)
357 # the function a weak reference to itself to avoid a reference cycle.
--> 358 return weak_wrapped_fn().__wrapped__(*args, **kwds)
359 weak_wrapped_fn = weakref.ref(wrapped_fn)
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/func_graph.py in wrapper(*args, **kwargs)
904 if hasattr(e, "ag_error_metadata"):
--> 905 raise e.ag_error_metadata.to_exception(e)
906 else:
OperatorNotAllowedInGraphError: in converted code:
<ipython-input-2-d2d9c7117621>:15 bpr_triplet_loss *
anchor_latent, positive_item_latent, negative_item_latent = inputs
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:547 __iter__
self._disallow_iteration()
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:540 _disallow_iteration
self._disallow_when_autograph_enabled("iterating over `tf.Tensor`")
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:518 _disallow_when_autograph_enabled
" decorating it directly with @tf.function.".format(task))
OperatorNotAllowedInGraphError: iterating over `tf.Tensor` is not allowed: AutoGraph did not convert this function. Try decorating it directly with @tf.function.
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call last)
<ipython-input-8-083f67ca66a0> in <module>
----> 1 model = getModel(n_users, n_items)
<ipython-input-6-75edf8b5cf85> in getModel(n_users, n_items, emb_dim)
20 # Triplet loss function
21 output = concatenate([user_vecs, pos_item_vecs, neg_item_vecs])
---> 22 loss = Lambda(bpr_triplet_loss, (1,))(output)
23
24 model = Model(inputs=[anchor, positive, negative], outputs=loss)
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/base_layer.py in __call__(self, inputs, *args, **kwargs)
852 'dynamic. Pass `dynamic=True` to the class '
853 'constructor.\nEncountered error:\n"""\n' +
--> 854 str(e) + '\n"""')
855 else:
856 # We will use static shape inference to return symbolic tensors
TypeError: You are attempting to use Python control flow in a layer that was not declared to be dynamic. Pass `dynamic=True` to the class constructor.
Encountered error:
"""
in converted code:
<ipython-input-2-d2d9c7117621>:15 bpr_triplet_loss *
anchor_latent, positive_item_latent, negative_item_latent = inputs
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:547 __iter__
self._disallow_iteration()
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:540 _disallow_iteration
self._disallow_when_autograph_enabled("iterating over `tf.Tensor`")
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:518 _disallow_when_autograph_enabled
" decorating it directly with @tf.function.".format(task))
OperatorNotAllowedInGraphError: iterating over `tf.Tensor` is not allowed: AutoGraph did not convert this function. Try decorating it directly with @tf.function.
"""
note tf.executing_eagerly()
给出 True
正如我在 Tensorflow 2.0.0
报错信息有误,是报错的bug。
主要问题是 autograph 当前不处理张量解包。它隐藏在多层堆栈跟踪中,但这是指向错误的行:
<ipython-input-2-d2d9c7117621>:15 bpr_triplet_loss *
anchor_latent, positive_item_latent, negative_item_latent = inputs
所以你必须手动解压张量:anchor_latent, positive_item_latent, negative_item_latent = tf.unstack(inputs)
我正在努力在 tensorflow 中重现一个简单的代码。
我有自己定义的函数用作我的模型的指标。
这是一个简单的三元组损失函数(稍作修改),但如果我使用普通的损失函数,问题仍然是一样的。
import pandas as pd
import numpy as np
import tensorflow as tf
from tensorflow.keras.activations import sigmoid
from tensorflow.keras import backend
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.layers import Input, Embedding, Flatten, Dense, Dropout, Lambda, dot, concatenate
@tf.function
def bpr_triplet_loss(inputs):
anchor_latent, positive_item_latent, negative_item_latent = inputs
# BPR loss
loss = 1.0 - backend.sigmoid(
backend.sum(anchor_latent * positive_item_latent, axis=-1, keepdims=True) -
backend.sum(anchor_latent * negative_item_latent, axis=-1, keepdims=True))
return loss
def getModel(n_users, n_items, emb_dim = 20):
# Input Layers
user_input = Input(shape=[1], name = 'user_input')
pos_item_input = Input(shape=[1], name = 'pos_item_input')
neg_item_input = Input(shape=[1], name = 'neg_item_input')
# Embedding Layers
# Shared embedding layer for positive and negative items
user_embedding = Embedding(output_dim=emb_dim, input_dim=n_users + 1, input_length=1, name='user_emb')(user_input)
item_embedding = Embedding(output_dim=emb_dim, input_dim=n_items + 1, input_length=1, name='item_emb')
pos_item_embedding = item_embedding(pos_item_input)
neg_item_embedding = item_embedding(neg_item_input)
user_vecs = Flatten()(user_embedding)
pos_item_vecs = Flatten()(pos_item_embedding)
neg_item_vecs = Flatten()(neg_item_embedding)
# Triplet loss function
output = concatenate([user_vecs, pos_item_vecs, neg_item_vecs])
loss = Lambda(bpr_triplet_loss, (1,))(output)
model = Model(inputs=[anchor, positive, negative], outputs=loss)
model.compile(optimizer='Adam', loss='mse',
metrics=["mae"])
# Define and Compile Model
#model = Model(inputs = [user_input, pos_item_input, neg_item_input], outputs = output)
#model.compile(optimizer='Adam', loss=bpr_triplet_loss, metrics=[bpr_triplet_loss])
return model
model = getModel(n_users, n_items) # 6706, 3040
当我 运行 这段代码时,我得到以下(开始令人沮丧的)错误
---------------------------------------------------------------------------
OperatorNotAllowedInGraphError Traceback (most recent call last)
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/base_layer.py in __call__(self, inputs, *args, **kwargs)
841 with auto_control_deps.AutomaticControlDependencies() as acd:
--> 842 outputs = call_fn(cast_inputs, *args, **kwargs)
843 # Wrap Tensors in `outputs` in `tf.identity` to avoid
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/keras/layers/core.py in call(self, inputs, mask, training)
794 with variable_scope.variable_creator_scope(self._variable_creator):
--> 795 return self.function(inputs, **arguments)
796
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py in __call__(self, *args, **kwds)
456 tracing_count = self._get_tracing_count()
--> 457 result = self._call(*args, **kwds)
458 if tracing_count == self._get_tracing_count():
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py in _call(self, *args, **kwds)
502 initializer_map = object_identity.ObjectIdentityDictionary()
--> 503 self._initialize(args, kwds, add_initializers_to=initializer_map)
504 finally:
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py in _initialize(self, args, kwds, add_initializers_to)
407 self._stateful_fn._get_concrete_function_internal_garbage_collected( # pylint: disable=protected-access
--> 408 *args, **kwds))
409
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py in _get_concrete_function_internal_garbage_collected(self, *args, **kwargs)
1847 args, kwargs = None, None
-> 1848 graph_function, _, _ = self._maybe_define_function(args, kwargs)
1849 return graph_function
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py in _maybe_define_function(self, args, kwargs)
2149 if graph_function is None:
-> 2150 graph_function = self._create_graph_function(args, kwargs)
2151 self._function_cache.primary[cache_key] = graph_function
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py in _create_graph_function(self, args, kwargs, override_flat_arg_shapes)
2040 override_flat_arg_shapes=override_flat_arg_shapes,
-> 2041 capture_by_value=self._capture_by_value),
2042 self._function_attributes,
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/func_graph.py in func_graph_from_py_func(name, python_func, args, kwargs, signature, func_graph, autograph, autograph_options, add_control_dependencies, arg_names, op_return_value, collections, capture_by_value, override_flat_arg_shapes)
914
--> 915 func_outputs = python_func(*func_args, **func_kwargs)
916
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py in wrapped_fn(*args, **kwds)
357 # the function a weak reference to itself to avoid a reference cycle.
--> 358 return weak_wrapped_fn().__wrapped__(*args, **kwds)
359 weak_wrapped_fn = weakref.ref(wrapped_fn)
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/func_graph.py in wrapper(*args, **kwargs)
904 if hasattr(e, "ag_error_metadata"):
--> 905 raise e.ag_error_metadata.to_exception(e)
906 else:
OperatorNotAllowedInGraphError: in converted code:
<ipython-input-2-d2d9c7117621>:15 bpr_triplet_loss *
anchor_latent, positive_item_latent, negative_item_latent = inputs
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:547 __iter__
self._disallow_iteration()
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:540 _disallow_iteration
self._disallow_when_autograph_enabled("iterating over `tf.Tensor`")
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:518 _disallow_when_autograph_enabled
" decorating it directly with @tf.function.".format(task))
OperatorNotAllowedInGraphError: iterating over `tf.Tensor` is not allowed: AutoGraph did not convert this function. Try decorating it directly with @tf.function.
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call last)
<ipython-input-8-083f67ca66a0> in <module>
----> 1 model = getModel(n_users, n_items)
<ipython-input-6-75edf8b5cf85> in getModel(n_users, n_items, emb_dim)
20 # Triplet loss function
21 output = concatenate([user_vecs, pos_item_vecs, neg_item_vecs])
---> 22 loss = Lambda(bpr_triplet_loss, (1,))(output)
23
24 model = Model(inputs=[anchor, positive, negative], outputs=loss)
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/base_layer.py in __call__(self, inputs, *args, **kwargs)
852 'dynamic. Pass `dynamic=True` to the class '
853 'constructor.\nEncountered error:\n"""\n' +
--> 854 str(e) + '\n"""')
855 else:
856 # We will use static shape inference to return symbolic tensors
TypeError: You are attempting to use Python control flow in a layer that was not declared to be dynamic. Pass `dynamic=True` to the class constructor.
Encountered error:
"""
in converted code:
<ipython-input-2-d2d9c7117621>:15 bpr_triplet_loss *
anchor_latent, positive_item_latent, negative_item_latent = inputs
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:547 __iter__
self._disallow_iteration()
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:540 _disallow_iteration
self._disallow_when_autograph_enabled("iterating over `tf.Tensor`")
/opt/conda/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py:518 _disallow_when_autograph_enabled
" decorating it directly with @tf.function.".format(task))
OperatorNotAllowedInGraphError: iterating over `tf.Tensor` is not allowed: AutoGraph did not convert this function. Try decorating it directly with @tf.function.
"""
note tf.executing_eagerly()
给出 True
正如我在 Tensorflow 2.0.0
报错信息有误,是报错的bug。
主要问题是 autograph 当前不处理张量解包。它隐藏在多层堆栈跟踪中,但这是指向错误的行:
<ipython-input-2-d2d9c7117621>:15 bpr_triplet_loss *
anchor_latent, positive_item_latent, negative_item_latent = inputs
所以你必须手动解压张量:anchor_latent, positive_item_latent, negative_item_latent = tf.unstack(inputs)