@tf.function-跟踪(tracing)-传递python参数

传递不同的python参数会触发跟踪

与其他TensorFlow操作不同,不会将python数值输入转换为tensor

传递 不同的 python参数,会触发跟踪,并且创建图(下面介绍),消耗资源

@tf.function
def f(a):
    print("print()::",a)
    tf.print("tf.print()::",a)

第一次调用,会触发跟踪

执行下面代码:

f(1)

结果如下:

print():: 1
tf.print():: 1

执行了print("print()::",a)语句,说明触发跟踪

再次调用,传递相同的python参数

再次执行

f(1)

结果如下:

tf.print():: 1

没有执行print("print()::",a)语句,说明:传递相同的python参数,不会跟踪

再次调用,传递不相同的python参数

再次执行

f(2)

结果如下:

print():: 2
tf.print():: 2

传递不同的python参数,会触发跟踪

跟踪函数后,会创建图

跟踪 函数后,TensorFlow在后台会 创建图

通过函数名.get_concrete_function(参数).graph获取图

例子:

f.get_concrete_function(1).graph

表示调用函数f(),并传递参数1,然后获取该函数的图

传递相同的python参数,获取图

执行下面代码

print(f.get_concrete_function(1).graph)
print(f.get_concrete_function(2).graph)

结果如下:

FuncGraph(name=f, id=5187505424)
FuncGraph(name=f, id=5184343952)

从id可知,这是2个图,传递1时创建一个图,传递2时创建另一个图

注意:

  • 没有执行print("print()::",a)语句,说明没有跟踪,也就没有创建新的图。因为在上面调用函数f(1) 和 f(2)了

  • 此时不会执行tf.print("tf.print()::",a)语句

传递不同的python参数,获取图

执行下面代码

print(f.get_concrete_function(10).graph)
print(f.get_concrete_function(20).graph)

结果如下:

print():: 10
FuncGraph(name=f, id=5066969936)
print():: 20
FuncGraph(name=f, id=5067122256)

2次调用,都执行了print("print()::",a)语句,说明传递10时创建一个图,传递20时创建另一个图。

2个图的id不相同,确实是创建2个图

总结

由于传递 不同 的python参数会 触发跟踪,TensorFlow在后台会 创建图,也就意味着 消耗资源。

这种消耗资源是没有必要的,所以尽量不要传递python参数,而是传递tensor张量

传递python参数的应用场景

仅当Python数值参数采用很少的不同值(例如超参数(如神经网络中的层数))时才应使用。


原文出处:/show_1EF5Hngv4moE.html