Python 如果条件输出,则用@tf.function修饰
我试图评估变量a是否为空(即hasPython 如果条件输出,则用@tf.function修饰,python,tensorflow,tensorflow2.0,Python,Tensorflow,Tensorflow2.0,我试图评估变量a是否为空(即hassize==0)。但是,当使用@tf.function装饰代码时,if语句的计算结果错误地为True,而当删除装饰器时,它的计算结果为Falsetf.size(a)似乎在这两种情况下都正确地计算为0。如何解决这个问题 将tensorflow导入为tf a=tf.Variable([[])) @功能 def测试(a): 打印尺寸=tf.print(tf.size(a)) 印刷品(tf.尺寸(a)) 如果tf.math.不相等(tf.size(a),0): 打印('
size==0
)。但是,当使用@tf.function
装饰代码时,if语句的计算结果错误地为True,而当删除装饰器时,它的计算结果为Falsetf.size(a)
似乎在这两种情况下都正确地计算为0。如何解决这个问题
将tensorflow导入为tf
a=tf.Variable([[]))
@功能
def测试(a):
打印尺寸=tf.print(tf.size(a))
印刷品(tf.尺寸(a))
如果tf.math.不相等(tf.size(a),0):
打印('失败')
使用tf.control_依赖项([print_op]):
一无所获
测试(a)
这有点让人头疼,但是,一旦我们了解到tf.function
正在将python操作和控制流映射到tf图,而裸函数只是急切地执行,我们就可以通过它进行挑选,这就更有意义了
我已经调整了你的例子来说明发生了什么。考虑<代码> TEST1和<代码> TEST2如下:
@tf.function
def测试1(a):
打印尺寸=tf.print(tf.size(a))
打印(“python打印大小:{}”。格式(tf.size(a)))
如果tf.math.不相等(tf.size(a),0):
打印('失败')
使用tf.control_依赖项([print_op]):
一无所获
def测试2(a):
打印尺寸=tf.print(tf.size(a))
打印(“python打印大小:{}”。格式(tf.size(a)))
如果tf.math.不相等(tf.size(a),0):
打印('失败')
使用tf.control_依赖项([print_op]):
一无所获
除了@tf.function
装饰器之外,它们彼此相同
现在执行test2(tf.Variable([[]])
将为我们提供:
0
python print size: 0
0
python print size: 0
这是我想你会期待的行为。而test1(tf.Variable([[]))
给出:
python print size: Tensor("Size_1:0", shape=(), dtype=int32)
fail
0
关于此输出,您可能会发现一些令人惊讶的事情(除了失败
):
print()
和print()
的顺序颠倒了tf.print()
@tf.function
我们不再拥有python函数,而是使用autograph从函数代码映射tf图。这意味着,在计算if
条件时,我们还没有执行tf.math.not_equal(tf.size(a),0)
,只有一个对象(一个Tensor
对象的实例),在python中,它是真实的:
class-MyClass:
通过
my_obj=MyClass()
如果(我的目标):
打印(“我的对象计算为真”)##输出“我的对象计算为真”
这意味着,在计算tf.math.not_equal(tf.size(a),0)
之前,我们在test1
中得到print('fail')
语句
那么解决办法是什么
好的,如果我们在if
块中删除对python onlyprint()
函数的调用,并将其替换为对签名友好的tf.print()
语句,那么签名将无缝地转换我们的if。。。else…
将逻辑转换为图形友好的tf.cond
语句,以确保一切按正确顺序进行:
def test3(a):
print_op = tf.print(tf.size(a))
print("python print size: {}".format(tf.size(a)))
if tf.math.not_equal(tf.size(a),0):
tf.print('fail')
with tf.control_dependencies([print_op]):
return None