今天遇到一个诡异的问题:class中用tf.function修饰的成员函数,在使用if、while等语句时条件用‘\’符号换行会报错,demo如下。
环境:python-3.7 tensorflow-2.1.0
import tensorflow as tf
class T(object):
@tf.function
def test(self, x):
if \
x == 0:
pass
t = T()
t.test(tf.constant(0))
控制台信息如下:
WARNING:tensorflow:AutoGraph could not transform <bound method T.test of <tensorflow.python.eager.function.TfMethodTarget object at 0x114b90650>> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, export AUTOGRAPH_VERBOSITY=10
) and attach the full output.
Cause: expected an indented block (, line 5)
Traceback (most recent call last):
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/autograph/impl/api.py”, line 526, in converted_call
converted_f = conversion.convert(target_entity, program_ctx)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/autograph/impl/conversion.py”, line 326, in convert
free_nonglobal_var_names)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/autograph/impl/conversion.py”, line 240, in _convert_with_cache
entity, program_ctx)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/autograph/impl/conversion.py”, line 475, in convert_entity_to_ast
nodes, name, entity_info = convert_func_to_ast(o, program_ctx)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/autograph/impl/conversion.py”, line 634, in convert_func_to_ast
node, source = parser.parse_entity(f, future_features=future_features)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/autograph/pyct/parser.py”, line 207, in parse_entity
return _attempt_to_parse_normal_source(source, future_features)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/autograph/pyct/parser.py”, line 111, in _attempt_to_parse_normal_source
return parse_str(source, preamble_len=len(future_features)), source
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/autograph/pyct/parser.py”, line 224, in parse_str
module_node = gast.parse(src)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/gast/gast.py”, line 240, in parse
return ast_to_gast(_ast.parse(*args, **kwargs))
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/ast.py”, line 35, in parse
return compile(source, filename, mode, PyCF_ONLY_AST)
File “”, line 5
pass
^
IndentationError: expected an indented block
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “”, line 1, in
File “/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_umd.py”, line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File “/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py”, line 18, in execfile
exec(compile(contents+"\n", file, ‘exec’), glob, loc)
File “/Users/guliqi/Desktop/kws/aaa.py”, line 12, in
t.test(tf.constant(0))
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py”, line 568, in call
result = self._call(*args, **kwds)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py”, line 615, in _call
self._initialize(args, kwds, add_initializers_to=initializers)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py”, line 497, in _initialize
*args, **kwds))
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py”, line 2389, in _get_concrete_function_internal_garbage_collected
graph_function, _, _ = self._maybe_define_function(args, kwargs)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py”, line 2703, in _maybe_define_function
graph_function = self._create_graph_function(args, kwargs)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py”, line 2593, in _create_graph_function
capture_by_value=self._capture_by_value),
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/framework/func_graph.py”, line 978, in func_graph_from_py_func
func_outputs = python_func(*func_args, **func_kwargs)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py”, line 439, in wrapped_fn
return weak_wrapped_fn().wrapped(*args, **kwds)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py”, line 3211, in bound_method_wrapper
return wrapped_fn(*args, **kwargs)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/framework/func_graph.py”, line 964, in wrapper
user_requested=True,
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/autograph/impl/api.py”, line 560, in converted_call
return call_unconverted(f, args, kwargs, options)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/autograph/impl/api.py”, line 326, in call_unconverted
return f.self.call(args, kwargs)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py”, line 3173, in call
return wrapped_fn(self.weakrefself_target(), *args, **kwargs)
File “/Users/guliqi/Desktop/kws/aaa.py”, line 8, in test
x == 0:
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py”, line 757, in bool
self._disallow_bool_casting()
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py”, line 523, in _disallow_bool_casting
"using a tf.Tensor
as a Python bool
“)
File “/Users/guliqi/anaconda3/envs/ai/lib/python3.7/site-packages/tensorflow_core/python/framework/ops.py”, line 510, in _disallow_when_autograph_enabled
" decorating it directly with @tf.function.”.format(task))
tensorflow.python.framework.errors_impl.OperatorNotAllowedInGraphError: using a tf.Tensor
as a Python bool
is not allowed: AutoGraph did not convert this function. Try decorating it directly with @tf.function.
报错信息为 IndentationError: expected an indented block,但实际上不存在空格和tab的问题。
之后我做了更进一步的尝试,代码和结果如下
- 取消换行。无报错。
import tensorflow as tf
class T(object):
@tf.function
def test(self, x):
if x == 0:
pass
t = T()
t.test(tf.constant(0))
- 换行但传入参数为int而不是tf.constant。无报错但提示WARNING。
WARNING:tensorflow:AutoGraph could not transform <bound method T.test of <tensorflow.python.eager.function.TfMethodTarget object at 0x10e798fd0>> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux,export AUTOGRAPH_VERBOSITY=10
) and attach the full output.
Cause: expected an indented block (, line 5)
import tensorflow as tf
class T(object):
@tf.function
def test(self, x):
if \
x == 0:
pass
t = T()
t.test(0)
- 去除tf.function修饰。无报错。
class T(object):
def test(self, x):
if \
x == 0:
pass
t = T()
t.test(tf.constant(0))
- 作为一个普通的函数而非类的成员函数。无报错。
@tf.function
def test(x):
if \
x == 0:
pass
test(tf.constant(0))
现在出错的具体原因未知,如果有知道的朋友可以留言或者一起探讨,蟹蟹。
3.31更新:google了一下发现这的确是tensorflow的bug,github上已经有人提交这个issue了。https://github.com/tensorflow/tensorflow/issues/35765