1. 变量与命名方法

Tensorflow当中有两种途径生成变量variable:

  • tf.Variable()
  • tf.get_variable()

命名方法也有两种:

  • tf.name_scope()
  • tf.variable_scope()

tf.name_scope() 的框架下,两中变量生成方法的使用结果如下:

  1. import tensorflow as tf
  2. with tf.name_scope("a_name_scope"):
  3. initializer = tf.constant_initializer(value=1)
  4. var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
  5. var2 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
  6. var21 = tf.Variable(name='var2', initial_value=[2.1], dtype=tf.float32)
  7. var22 = tf.Variable(name='var2', initial_value=[2.2], dtype=tf.float32)
  8. with tf.Session() as sess:
  9. sess.run(tf.initialize_all_variables())
  10. print(var1.name) # var1:0
  11. print(sess.run(var1)) # [ 1.]
  12. print(var2.name) # a_name_scope/var2:0
  13. print(sess.run(var2)) # [ 2.]
  14. print(var21.name) # a_name_scope/var2_1:0
  15. print(sess.run(var21)) # [ 2.1]
  16. print(var22.name) # a_name_scope/var2_2:0
  17. print(sess.run(var22)) # [ 2.2]

可以看出,使用 tf.Variable() 定义的时候, 虽然name都一样, 但是为了不重复变量名, Tensorflow 输出的变量名并不是一样的,本质上var2, var21, var22并不是一样的变量。而另一方面, 使用tf.get_variable() 义的变量不会被tf.name_scope()当中的名字所影响。
tf.variable_scope() 的框架下,两中变量生成方法的使用结果如下:

  1. with tf.variable_scope("a_variable_scope") as scope:
  2. initializer = tf.constant_initializer(value=3)
  3. var3 = tf.get_variable(name='var3', shape=[1], dtype=tf.float32, initializer=initializer)
  4. scope.reuse_variables()
  5. var3_reuse = tf.get_variable(name='var3',)
  6. var4 = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)
  7. var4_reuse = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)
  8. with tf.Session() as sess:
  9. sess.run(tf.global_variables_initializer())
  10. print(var3.name) # a_variable_scope/var3:0
  11. print(sess.run(var3)) # [ 3.]
  12. print(var3_reuse.name) # a_variable_scope/var3:0
  13. print(sess.run(var3_reuse)) # [ 3.]
  14. print(var4.name) # a_variable_scope/var4:0
  15. print(sess.run(var4)) # [ 4.]
  16. print(var4_reuse.name) # a_variable_scope/var4_1:0
  17. print(sess.run(var4_reuse)) # [ 4.]

如果想要达到重复利用变量的效果, 我们就要使用 tf.variable_scope() , 并搭配 tf.get_variable() 这种方式产生和提取变量。不像 tf.Variable() 每次都会产生新的变量, tf.get_variable() 如果遇到了同样名字的变量时, 它会单纯的提取这个同样名字的变量(避免产生新变量). 而在重复使用的时候, 一定要在代码中强调 scope.reuse_variables() , 否则系统将会报错, 以为你只是单纯的不小心重复使用到了一个变量。
总结一下:

  • tf.Variable() 每次都会产生新的变量,即便名字相同,也会产生新的变量,并在内部把名字变为不同的名字;而 tf.get_variable() 先查看名字下是否有同样名字的变量,若没有就直接创建新变量,若有就看该变量是否被标记为可不用,即 scope.reuse_variables() ,否则报错。
  • 想重复利用变量时tf.variable_scope() scope.reuse_variables()tf.get_variable() 搭配使用。经常用语比如RNN代码中: ```python class TrainConfig: batch_size = 20 time_steps = 20 input_size = 10 output_size = 2 cell_size = 11 learning_rate = 0.01

class TestConfig(TrainConfig): time_steps = 1

train_config = TrainConfig() test_config = TestConfig()

with tf.variable_scope(‘rnn’) as scope: sess = tf.Session() train_rnn = RNN(train_config) scope.reuse_variables() test_rnn = RNN(test_config) sess.run(tf.global_variables_initializer()) ``` 在training RNN和test RNN的时候, RNN的time_steps会有不同的取值, 这将会影响到整个RNN的结构, 所以导致在test的时候, 不能单纯地使用training时建立的那个 RNN。但是training RNN和test RNN又必须是有同样的weights biases的参数。所以, 这时就是使用reuse variable的好时机。

疑难杂症

目前tensorflow不支持python3.7以上的版本,这里需要特别注意,python需配合3.6及以下的环境。
tensorflow版本繁杂,经常容易因为pip下载的版本不对,导致程序报错。
tensorflow_hub必须在tensorflow1.7以后使用。

Tensorflow2与1的区别

0. 高级API

tensorflow2将Keras高级封装API作为默认推荐用法,不过仍提供底层接口以便于更自定义的操作。

1. Eager execution

tensorflow1必须先定义计算图,在利用session进行执行,而2不必。借鉴了pytorch和Chainer深度学习框架的思想,而且Keras也同样兼容Eager execution(渴望执行)。

参考文献

  1. 莫烦PYTHON
  2. tensorflow快速入门