變量共享主要涉及到兩個函數: tf.get_variable(<name>, <shape>, <initializer>) 和 tf.variable_scope(<scope_name>)。
爲什麼要共享變量?
例如如下代碼:
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)
v=tf.get_variable(<name>, <shape>, <initializer>)
此調用做了有關作用域的兩件事中的其中之一,方法調入 . 總的有兩種情況 .
情況 1: 當 tf.get_variable_scope().reuse == False 時,作用域就是 爲創建新變量所設置的 .這種情況下,v 將通過 tf.Variable 所提供的形狀和數據類型來重新創建 . 創建
變量的全稱將會由當前變量作用域名 + 所提供的名字所組成 , 並且還會檢查來確保沒 有任何變量使用這個全稱 . 如果這個全稱已經有一個變量使用了,那麼方法將會拋出
ValueError 錯誤 .-----------------------------------------result1= my_image_filter(image1)
情況 2 :當 tf.get_variable_scope().reuse == True 時,作用域是爲重 用變量所設置,這種情況下,調用就會搜索一個已經存在的變量,他的全稱和當前變量的作用域名
+ 所提供的名字是否相等 . 如果不存在相應的變量,就會拋出 ValueError 錯誤 . 如果變量找到了,就返回這個變量 .
tf.variable_scope()是怎麼工作?
tf.variable_scope(<scope_name>)
變量作用域的主方法帶有一個名稱,它將會作爲前綴用於變量名 , 並且帶有一個重用標籤來區分以上的兩種情況 .當前變量作用域可以用 tf.get_variable_scope() 進行檢索並且 reuse 標籤可以通過調用 tf.get_variable_scope().reuse_variables() 設置爲 True