4-3,AutoGraph的使用规范

有三种计算图的构建方式:静态计算图,动态计算图,以及Autograph。

TensorFlow 2.0主要使用的是动态计算图和Autograph。

动态计算图易于调试,编码效率较高,但执行效率偏低。

静态计算图执行效率很高,但较难调试。

而Autograph机制可以将动态图转换成静态计算图,兼收执行效率和编码效率之利。

当然Autograph机制能够转换的代码并不是没有任何约束的,有一些编码规范需要遵循,否则可能会转换失败或者不符合预期。

我们将着重介绍Autograph的编码规范和Autograph转换成静态图的原理。

并介绍使用tf.Module来更好地构建Autograph。

本篇我们介绍使用Autograph的编码规范。

一,Autograph编码规范总结

  • 1,被@tf.function修饰的函数应尽可能使用TensorFlow中的函数而不是Python中的其他函数。例如使用tf.print而不是print,使用tf.range而不是range,使用tf.constant(True)而不是True.

  • 2,避免在@tf.function修饰的函数内部定义tf.Variable.

  • 3,被@tf.function修饰的函数不可修改该函数外部的Python列表或字典等数据结构变量。

二,Autograph编码规范解析

1,被@tf.function修饰的函数应尽量使用TensorFlow中的函数而不是Python中的其他函数。

  1. import numpy as np
  2. import tensorflow as tf
  3. @tf.function
  4. def np_random():
  5. a = np.random.randn(3,3)
  6. tf.print(a)
  7. @tf.function
  8. def tf_random():
  9. a = tf.random.normal((3,3))
  10. tf.print(a)
  1. #np_random每次执行都是一样的结果。
  2. np_random()
  3. np_random()
  1. array([[ 0.22619201, -0.4550123 , -0.42587565],
  2. [ 0.05429906, 0.2312667 , -1.44819738],
  3. [ 0.36571796, 1.45578986, -1.05348983]])
  4. array([[ 0.22619201, -0.4550123 , -0.42587565],
  5. [ 0.05429906, 0.2312667 , -1.44819738],
  6. [ 0.36571796, 1.45578986, -1.05348983]])
  1. #tf_random每次执行都会有重新生成随机数。
  2. tf_random()
  3. tf_random()
  1. [[-1.38956189 -0.394843668 0.420657277]
  2. [2.87235498 -1.33740318 -0.533843279]
  3. [0.918233037 0.118598573 -0.399486482]]
  4. [[-0.858178258 1.67509317 0.511889517]
  5. [-0.545829177 -2.20118237 -0.968222201]
  6. [0.733958483 -0.61904633 0.77440238]]

2,避免在@tf.function修饰的函数内部定义tf.Variable.

  1. # 避免在@tf.function修饰的函数内部定义tf.Variable.
  2. x = tf.Variable(1.0,dtype=tf.float32)
  3. @tf.function
  4. def outer_var():
  5. x.assign_add(1.0)
  6. tf.print(x)
  7. return(x)
  8. outer_var()
  9. outer_var()
  1. @tf.function
  2. def inner_var():
  3. x = tf.Variable(1.0,dtype = tf.float32)
  4. x.assign_add(1.0)
  5. tf.print(x)
  6. return(x)
  7. #执行将报错
  8. #inner_var()
  9. #inner_var()
  1. ---------------------------------------------------------------------------
  2. ValueError Traceback (most recent call last)
  3. <ipython-input-12-c95a7c3c1ddd> in <module>
  4. 7
  5. 8 #执行将报错
  6. ----> 9 inner_var()
  7. 10 inner_var()
  8. ~/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py in __call__(self, *args, **kwds)
  9. 566 xla_context.Exit()
  10. 567 else:
  11. --> 568 result = self._call(*args, **kwds)
  12. 569
  13. 570 if tracing_count == self._get_tracing_count():
  14. ......
  15. ValueError: tf.function-decorated function tried to create variables on non-first call.

3,被@tf.function修饰的函数不可修改该函数外部的Python列表或字典等结构类型变量。

  1. tensor_list = []
  2. #@tf.function #加上这一行切换成Autograph结果将不符合预期!!!
  3. def append_tensor(x):
  4. tensor_list.append(x)
  5. return tensor_list
  6. append_tensor(tf.constant(5.0))
  7. append_tensor(tf.constant(6.0))
  8. print(tensor_list)
  1. [<tf.Tensor: shape=(), dtype=float32, numpy=5.0>, <tf.Tensor: shape=(), dtype=float32, numpy=6.0>]
  1. tensor_list = []
  2. @tf.function #加上这一行切换成Autograph结果将不符合预期!!!
  3. def append_tensor(x):
  4. tensor_list.append(x)
  5. return tensor_list
  6. append_tensor(tf.constant(5.0))
  7. append_tensor(tf.constant(6.0))
  8. print(tensor_list)
  1. [<tf.Tensor 'x:0' shape=() dtype=float32>]

如果对本书内容理解上有需要进一步和作者交流的地方,欢迎在公众号”Python与算法之美”下留言。作者时间和精力有限,会酌情予以回复。

也可以在公众号后台回复关键字:加群,加入读者交流群和大家讨论。

image.png