@tf.function

需要掌握:tensorflow2的eager模式和graph模式

介绍

将函数编译成可调用的TensorFlow graph。

对深度神经网络进行优化,给性能带来巨大的提升,在GPU或TPU上运行,通过SavedModel导出模型参数

官网介绍:
https://www.tensorflow.org/api_docs/python/tf/function
https://www.tensorflow.org/guide/concrete_function
https://www.tensorflow.org/guide/function
https://www.tensorflow.org/tutorials/customization/performance#when_to_retrace

语法

tf.function(
    func=None,
    input_signature=None,
    autograph=True,
    experimental_implements=None,
    experimental_autograph_options=None, 
    experimental_relax_shapes=False,
    experimental_compile=None
)
参数
  • func:函数。此函数可使用if,for,while break,continue 等语句(在TensorFlow1.x中需要额外处理)

作为装饰器使用@tf.function

详细解释

tf.function构造一个可调用的 TensorFlow 图(tf.Graph),在 func函数中,跟踪编译TensorFlow操作,并有效地将 func函数 作为TensorFlow 图执行。

使用

用@tf.function修饰函数

import tensorflow as tf

@tf.function
def test():
    a=tf.constant(1)
    b=tf.constant(2)
    c=a+b
    print("a:",a)
    print("b:",b)
    print("c:",c)
    return c

res=test()
print(res)

执行结果如下:

a: Tensor("Const:0", shape=(), dtype=int32)
b: Tensor("Const_1:0", shape=(), dtype=int32)
c: Tensor("add:0", shape=(), dtype=int32)
tf.Tensor(3, shape=(), dtype=int32)

执行时,变量、加法运算,当做tf.Operation,只能看见形状,名字,看不见值,避免 python代码 和 TensorFlow 频繁交互、传输数据

可以通过tf.print()打印tensor的值

执行过程

由@tf.function装饰的函数的执行过程:

  1. 函数被执行并且被 跟踪 (tracing),所有的Tensorflow函数被当做tf.Operation进行图的创建.

  2. AutoGraph被唤醒,检测Python代码可以转为Tensorflow的逻辑,比如:

    while语句 转换为 tf.while_loop
    for 语句 转换为 tf.while_loop
    if 语句 转换为 tf.cond
    

    引自:https://www.tensorflow.org/tutorials/customization/performance#autograph_conditionals

  3. 对函数进行建图,为了保证Python代码中每一行的执行顺序,tf.control_dependencies被自动加入到代码中.保证第i行执行完后我们会执行第i+1行.

  4. 返回tf.Graph,根据函数名和输入参数,我们将这个graph存到一个cache中.

  5. 对于任何一个该函数的调用,我们会重复利用cache中的计算图进行计算.

Tracing(跟踪)

调用@tf.function修饰的函数时,可以对该函数传递 python对象 或者 tf.Tensors (可以是任意 形状、类型)

在调用时会跟踪(traces )该函数,在后台TensorFlow构建tf.Graph,进行运算

tf.keras

tf.keras下的类,如:Model、Sequential 支持@tf.function,不需要手动加上@tf.function装饰器

引自:
https://www.tensorflow.org/guide/concrete_function#interoperability_with_tfkeras

注意事项

常见注意

  1. 不要使用过于复杂的 python语句 和 python对象
  2. 不用numpy函数,改用tensorflow函数

函数内,不能使用tf.Variable

@tf.function
def test():
    a=tf.Variable(1)
test()

报错如下:

ValueError: tf.function-decorated function tried to create variables on non-first call.

tensor值在python代码中不可见

由@tf.function装饰下,tensor值在print()等python代码下不可见

@tf.function
def f(a):
    b=tf.constant(2)
    print("print()::",a)
    print("print()::",b)
    tf.print("tf.print()::",a)
    tf.print("tf.print()::",b)

执行下面代码

print():: Tensor("a:0", shape=(), dtype=int32)
print():: Tensor("Const:0", shape=(), dtype=int32)
tf.print():: 1
tf.print():: 2

在print()中只能看见tensor的name、shape、dtype,得不到值

同理也不能用if语句判断值,需要用tf.cond()
https://www.malaoshi.top/show_1EF5HE8ESMfb.html

通过tf.print()打印信息

详见上面

一个函数调用另一函数

当一个函数调用另一函数时,只需要修饰主函数即可(主函数调用的其他函数,也都会跟踪)

def add(a,b):
    print("add()--trace:",a,b)
    return a+b

@tf.function
def test(i):
    j=tf.constant(1)
    print("test()--trace:",i,j)
    add(i,j)

测试下面代码:

test(tf.constant(1))

执行结果:

test()--trace: Tensor("i:0", shape=(), dtype=int32) Tensor("Const:0", shape=(), dtype=int32)
add()--trace: Tensor("i:0", shape=(), dtype=int32) Tensor("Const:0", shape=(), dtype=int32)

在@tf.function装饰的函数中,不能使用list,改用tf.TensorArray

调试

启用graph模式后,无法debug,但可以通过tf.config.experimental_run_functions_eagerly(True)临时启用debug

@tf.function
def f(x):
  if x > 0:
    # Try setting a breakpoint here!
    # Example:
    #   import pdb
    #   pdb.set_trace()
    x = x + 1
  return x

tf.config.experimental_run_functions_eagerly(True)

# You can now set breakpoints and run the code in a debugger.
f(tf.constant(1))

tf.config.experimental_run_functions_eagerly(False)

引自:
https://www.tensorflow.org/guide/function#keras_and_autograph

注意 不是万能

不是所有的函数都可以通过@tf.function进行加速的,有的任务并不值得将函数转化为计算图形式,比如简单的矩阵乘法。

对于大量的计算,如对深度神经网络的优化,这一图转换能给性能带来巨大的提升。

应用场景

自定义训练模型,如:yolo等

感谢:
https://medium.com/@yaoyaowd/tensorflow-2-0%E4%B8%8A%E6%89%8B6-%E8%A7%A3%E5%89%96tf-function%E7%9A%84%E4%BD%BF%E7%94%A8-b48cef249ca4


原文出处:/show_1EF5HFCDp8fP.html