需要掌握: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装饰的函数的执行过程:
函数被执行并且被 跟踪 (tracing),所有的Tensorflow函数被当做
tf.Operation进行图的创建.AutoGraph被唤醒,检测Python代码可以转为Tensorflow的逻辑,比如:
while语句 转换为 tf.while_loop for 语句 转换为 tf.while_loop if 语句 转换为 tf.cond引自:https://www.tensorflow.org/tutorials/customization/performance#autograph_conditionals
对函数进行建图,为了保证Python代码中每一行的执行顺序,
tf.control_dependencies被自动加入到代码中.保证第i行执行完后我们会执行第i+1行.返回
tf.Graph,根据函数名和输入参数,我们将这个graph存到一个cache中.对于任何一个该函数的调用,我们会重复利用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
注意事项
常见注意
- 不要使用过于复杂的 python语句 和 python对象
- 不用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
