當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Python tf.compat.v1.variable_scope用法及代碼示例


用於定義創建變量(層)的操作的上下文管理器。

用法

tf.compat.v1.variable_scope(
    name_or_scope, default_name=None, values=None, initializer=None,
    regularizer=None, caching_device=None, partitioner=None, custom_getter=None,
    reuse=None, dtype=None, use_resource=None, constraint=None,
    auxiliary_name_scope=True
)

參數

  • name_or_scope stringVariableScope :要打開的範圍。
  • default_name 如果 name_or_scope 參數是 None ,則使用的默認名稱將是唯一的。如果提供了name_or_scope,它將不會被使用,因此它不是必需的並且可以是None。
  • values 傳遞給 op 函數的 Tensor 參數列表。
  • initializer 此範圍內變量的默認初始化程序。
  • regularizer 此範圍內變量的默認正則化器。
  • caching_device 此範圍內變量的默認緩存設備。
  • partitioner 此範圍內變量的默認分區器。
  • custom_getter 此範圍內變量的默認自定義 getter。
  • reuse True,無,或 tf.compat.v1.AUTO_REUSE;如果 True ,我們將進入此範圍以及所有 sub-scopes 的重用模式;如果 tf.compat.v1.AUTO_REUSE,我們創建變量,如果它們不存在,否則返回它們;如果沒有,我們繼承父作用域的重用標誌。當啟用即刻執行時,總是會創建新變量,除非 EagerVariableStore 或模板當前處於活動狀態。
  • dtype 在此範圍內創建的變量類型(默​​認為傳遞範圍內的類型,或從父範圍繼承)。
  • use_resource 如果為 False,所有變量都將是常規變量。如果為 True,則將使用具有明確語義的實驗性 ResourceVariables。默認為 False(稍後將更改為 True)。當啟用即刻執行時,此參數始終強製為 True。
  • constraint Optimizer 更新後應用於變量的可選投影函數(例如,用於實現層權重的範數約束或值約束)。該函數必須將表示變量值的未投影張量作為輸入,並返回投影值的張量(必須具有相同的形狀)。在進行異步分布式訓練時使用約束是不安全的。
  • auxiliary_name_scope 如果 True ,我們使用範圍創建一個輔助名稱範圍。如果 False ,我們不創建它。注意該參數不被繼承,隻在創建時生效一次。您隻應將其用於重新輸入預製變量範圍。

拋出

  • ValueError 嘗試在創建範圍內重用或在重用範圍內創建時。
  • TypeError 當某些參數的類型不合適時。

遷移到 TF2

警告:這個 API 是為 TensorFlow v1 設計的。繼續閱讀有關如何從該 API 遷移到本機 TensorFlow v2 等效項的詳細信息。見TensorFlow v1 到 TensorFlow v2 遷移指南有關如何遷移其餘代碼的說明。

盡管它是一個遺留的compat.v1 api,但隻要將tf.compat.v1.variable_scopetf.compat.v1.keras.utils.track_tf1_style_variables 裝飾器結合起來,tf.compat.v1.variable_scope 大部分與即刻執行和tf.function 兼容(盡管它的行為就像重用總是設置為AUTO_REUSE .)

有關遷移依賴於基於 variable_scope 的變量重用的代碼的更多信息,請參閱模型遷移指南。

當您在啟用了即刻執行但沒有 tf.compat.v1.keras.utils.track_tf1_style_variables 的情況下使用它時,tf.compat.v1.variable_scope 仍然能夠為在範圍內創建的變量的名稱添加前綴,但它不會啟用變量重用或 error-raising 檢查變量重用(get_variable在其中調用總是會創建新變量)。

從基於 get_variable 的變量重用機製切換後,要切換到 TF2 API,您隻需使用 tf.name_scope 為變量名稱添加前綴即可。

此上下文管理器驗證(可選)values 是否來自同一個圖,確保該圖是默認圖,並推送名稱範圍和變量範圍。

如果 name_or_scope 不是 None,則按原樣使用。如果name_or_scope 為無,則使用default_name。在這種情況下,如果之前在同一範圍內使用了相同的名稱,則將通過將 _N 附加到它來使其唯一。

變量範圍允許您創建新變量並共享已創建的變量,同時提供檢查以防止意外創建或共享。有關詳細信息,請參閱如何使用變量作用域,這裏我們僅提供幾個基本示例。

當禁用即刻執行時,變量範圍按預期工作。

tf.compat.v1.disable_eager_execution()

如何創建新變量的簡單示例:

with tf.compat.v1.variable_scope("foo"):
    with tf.compat.v1.variable_scope("bar"):
        v = tf.compat.v1.get_variable("v", [1])
        assert v.name == "foo/bar/v:0"

如何安全地重新輸入預製變量範圍的簡單示例:

with tf.compat.v1.variable_scope("foo") as vs:
  pass

# Re-enter the variable scope.
with tf.compat.v1.variable_scope(vs,
                       auxiliary_name_scope=False) as vs1:
  # Restore the original name_scope.
  with tf.name_scope(vs1.original_name_scope):
      v = tf.compat.v1.get_variable("v", [1])
      assert v.name == "foo/v:0"
      c = tf.constant([1], name="c")
      assert c.name == "foo/c:0"

請記住,一旦退出父作用域,default_name 的計數器就會被丟棄。因此,當代碼重新進入範圍時(例如通過保存它),所有嵌套的default_name 計數器都將重新啟動。

例如:

with tf.compat.v1.variable_scope("foo") as vs:
  with tf.compat.v1.variable_scope(None, default_name="bar"):
    v = tf.compat.v1.get_variable("a", [1])
    assert v.name == "foo/bar/a:0", v.name
  with tf.compat.v1.variable_scope(None, default_name="bar"):
    v = tf.compat.v1.get_variable("b", [1])
    assert v.name == "foo/bar_1/b:0"

with tf.compat.v1.variable_scope(vs):
  with tf.compat.v1.variable_scope(None, default_name="bar"):
    v = tf.compat.v1.get_variable("c", [1])
    assert v.name == "foo/bar/c:0"   # Uses bar instead of bar_2!

共享變量AUTO_REUSE的基本示例:

def foo():
  with tf.compat.v1.variable_scope("foo", reuse=tf.compat.v1.AUTO_REUSE):
    v = tf.compat.v1.get_variable("v", [1])
  return v

v1 = foo()  # Creates v.
v2 = foo()  # Gets the same, existing v.
assert v1 == v2

使用reuse=True 共享變量的基本示例:

with tf.compat.v1.variable_scope("foo"):
    v = tf.compat.v1.get_variable("v", [1])
with tf.compat.v1.variable_scope("foo", reuse=True):
    v1 = tf.compat.v1.get_variable("v", [1])
assert v1 == v

通過捕獲範圍和設置重用來共享變量:

with tf.compat.v1.variable_scope("foo") as scope:
    v = tf.compat.v1.get_variable("v", [1])
    scope.reuse_variables()
    v1 = tf.compat.v1.get_variable("v", [1])
assert v1 == v

為了防止意外共享變量,我們在非重用範圍內獲取現有變量時引發異常。

with tf.compat.v1.variable_scope("foo"):
    v = tf.compat.v1.get_variable("v", [1])
    v1 = tf.compat.v1.get_variable("v", [1])
    #  Raises ValueError("... v already exists ...").

同樣,我們在嘗試獲取重用模式下不存在的變量時引發異常。

with tf.compat.v1.variable_scope("foo", reuse=True):
    v = tf.compat.v1.get_variable("v", [1])
    #  Raises ValueError("... v does not exists ...").

請注意,reuse 標誌是繼承的:如果我們打開一個重用範圍,那麽它的所有 sub-scopes 也將成為重用。

關於名稱範圍的說明:設置 reuse 不會影響其他操作的命名,例如 mult。參見 github#6189 上的相關討論

請注意,直到版本 1.0(包括版本 1.0),允許(盡管明確不鼓勵)將 False 傳遞給重用參數,從而產生與 None 略有不同的未記錄行為。從 1.1.0 開始,傳遞 None 和 False 作為重用具有完全相同的效果。

關於在multi-threaded 環境中使用變量作用域的注意事項:變量作用域是線程本地的,因此一個線程不會看到另一個線程的當前作用域。此外,在使用 default_name 時,也僅在每個線程的基礎上生成唯一的範圍名稱。如果在不同的線程中使用了相同的名稱,則不會阻止新線程創建相同的範圍。但是,底層變量存儲是跨線程共享的(在同一個圖中)。因此,如果另一個線程試圖創建一個與前一個線程創建的變量同名的新變量,除非重用為 True,否則它將失敗。

此外,每個線程都以一個空的變量範圍開始。因此,如果您希望保留主線程範圍內的名稱前綴,您應該捕獲主線程的範圍並在每個線程中重新輸入它。例如

main_thread_scope = variable_scope.get_variable_scope()

# Thread's target function:
def thread_target_fn(captured_scope):
  with variable_scope.variable_scope(captured_scope):
    # .... regular code for this thread


thread = threading.Thread(target=thread_target_fn, args=(main_thread_scope,))

相關用法


注:本文由純淨天空篩選整理自tensorflow.org大神的英文原創作品 tf.compat.v1.variable_scope。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。