1.變量共享主要涉及兩個函數:
(1)tf.get_variable(name , shape , initializer )
(2) tf.variable_scope(scope_name)
tf.get_variable 和tf.Variable不同的一點是,前者擁有一個變量檢查機制,會檢測已經存在的變量是否設置爲共享變量,如果已經存在的變量沒有設置爲共享變量,TensorFlow 運行到第二個擁有相同名字的變量的時候,就會報錯。
def my_image_filter(input_images):
conv1_weights = tf.Variable(tf.random_normal([5, 5, 32, 32]),
name="conv1_weights")
conv1_biases = tf.Variable(tf.zeros([32]), name="conv1_biases")
conv1 = tf.nn.conv2d(input_images, conv1_weights,
strides=[1, 1, 1, 1], padding='SAME')
return tf.nn.relu(conv1 + conv1_biases)
有兩個變量(Variables)conv1_weighs, conv1_biases和一個操作(Op)conv1,如果你直接調用兩次,不會出什麼問題,但是會生成兩套變量;
# First call creates one set of 2 variables.
result1 = my_image_filter(image1)
# Another set of 2 variables is created in the second call.
result2 = my_image_filter(image2)
如果把 tf.Variable 改成 tf.get_variable,直接調用兩次,就會出問題了:
result1 = my_image_filter(image1)
result2 = my_image_filter(image2)
# Raises ValueError(... conv1/weights already exists ...)
爲了解決這個問題,TensorFlow 又提出了 tf.variable_scope 函數:它的主要作用是,在一個作用域 scope 內共享一些變量,可以有如下幾種用法:
1)
with tf.variable_scope("image_filters") as scope:
result1 = my_image_filter(image1)
scope.reuse_variables() # or
#tf.get_variable_scope().reuse_variables()
result2 = my_image_filter(image2)
需要注意的是:最好不要設置 reuse 標識爲 False,只在需要的時候設置 reuse 標識爲 True。
2)
with tf.variable_scope("image_filters1") as scope1:
result1 = my_image_filter(image1)
with tf.variable_scope(scope1, reuse = True)
result2 = my_image_filter(image2)
通常情況下,tf.variable_scope 和 tf.name_scope 配合,能畫出非常漂亮的流程圖,但是他們兩個之間又有着細微的差別,那就是 name_scope 只能管住操作 Ops 的名字,而管不住變量 Variables 的名字,看下例:
二、當需要重複使用共享權重。但是tensorflow默認是不允許重複使用變量的,會報一些InvalidArgumentError或者Attemping to use uninitialized value等錯誤。解決辦法是使用variable_scope,並且設置該variable_scope的reuse=True. 設置方法有兩個:
with tf.variable_scope(scope_name,reuse=True):
#or
tf.get_variable_scope.reuse_variables()