【譯】Effective TensorFlow Chapter3——範圍以及何時使用它們
本文翻譯自: 《Scopes and when to use them》, 如有侵權請聯絡刪除,僅限於學術交流,請勿商用。如有謬誤,請聯絡指出。
TensorFlow中的變數和張量具有name屬性,用於在符號圖中標識它們。如果在建立變數或張量時未指定名稱,TensorFlow會自動為您指定名稱:
a = tf.constant(1)
print(a.name) # prints "Const:0"
b = tf.Variable(1)
print(b.name) # prints "Variable:0"
複製程式碼
您可以通過顯式指定來覆蓋預設名稱:
a = tf.constant(1, name="a" )
print(a.name) # prints "a:0"
b = tf.Variable(1, name="b")
print(b.name) # prints "b:0"
複製程式碼
TensorFlow引入了兩個不同的上下文管理器來改變張量和變數的名稱。第一個是tf.name_scope
:
with tf.name_scope("scope"):
a = tf.constant(1, name="a")
print(a.name) # prints "scope/a:0"
b = tf.Variable(1, name="b")
print(b.name) # prints "scope/b:0"
c = tf.get_variable(name="c", shape=[])
print(c.name) # prints "c:0"
複製程式碼
請注意,有兩種方法可以在TensorFlow中定義新變數,一是建立tf.Variable
物件或是呼叫tf.get_variable
方法。使用新名稱呼叫tf.get_variable
會導致建立新變數,但如果存在具有相同名稱的變數,則會引發ValueError異常,告訴我們不允許重新宣告變數。
tf.name_scope
影響使用tf.Variable
建立的張量和變數的名稱,但不影響使用tf.get_variable
建立的變數。
與tf.name_scope
tf.variable_scope
也修改了使用tf.get_variable
建立的變數的名稱:
with tf.variable_scope("scope"):
a = tf.constant(1, name="a")
print(a.name) # prints "scope/a:0"
b = tf.Variable(1, name="b")
print(b.name) # prints "scope/b:0"
c = tf.get_variable(name="c", shape=[])
print(c.name) # prints "scope/c:0"
with tf.variable_scope("scope"):
a1 = tf.get_variable(name="a", shape=[])
a2 = tf.get_variable(name="a", shape=[]) # Disallowed
複製程式碼
但是,如果我們真的想要複用先前宣告的變數呢?變數範圍還提供了執行此操作的功能:
with tf.variable_scope("scope"):
a1 = tf.get_variable(name="a", shape=[])
with tf.variable_scope("scope", reuse=True):
a2 = tf.get_variable(name="a", shape=[]) # OK
複製程式碼
這在使用內建神經網路層時變得很方便:
with tf.variable_scope('my_scope'):
features1 = tf.layers.conv2d(image1, filters=32, kernel_size=3)
# Use the same convolution weights to process the second image:
with tf.variable_scope('my_scope', reuse=True):
features2 = tf.layers.conv2d(image2, filters=32, kernel_size=3)
複製程式碼
或者,您可以將reuse
屬性設定為tf.AUTO_REUSE
,這種操作告訴TensorFlow如果不存在具有相同名稱的變數,就建立新變數,否則就複用:
with tf.variable_scope("scope", reuse=tf.AUTO_REUSE):
features1 = tf.layers.conv2d(image1, filters=32, kernel_size=3)
with tf.variable_scope("scope", reuse=tf.AUTO_REUSE):
features2 = tf.layers.conv2d(image2, filters=32, kernel_size=3)
複製程式碼
如果你想共享很多變數,跟蹤定義新變數以及複用這些變數的時候可能很麻煩且容易出錯。tf.AUTO_REUSE
則簡化了此任務,但增加了共享不應共享的變數的風險。TensorFlow模板是解決這一問題的另一種方法,它沒有這種風險:
conv3x32 = tf.make_template("conv3x32", lambda x: tf.layers.conv2d(x, 32, 3))
features1 = conv3x32(image1)
features2 = conv3x32(image2) # Will reuse the convolution weights.
複製程式碼
您可以將任何功能轉換為TensorFlow模板。在第一次呼叫模板時,在函式內部定義的變數會被宣告,並且在連續呼叫中,它們將被自動複用。