![]() |
![]() |
![]() |
![]() |
TensorFlow 變數是表示程式操控的共用、持續狀態的建議方式。本指南涵蓋如何在 TensorFlow 中建立、更新和管理 tf.Variable
的執行個體。
變數是透過 tf.Variable
類別建立和追蹤的。tf.Variable
代表一個張量,其值可以透過對其執行運算來變更。透過特定的運算,您可以讀取和修改此張量的值。較高階的程式庫 (例如 tf.keras
) 使用 tf.Variable
來儲存模型參數。
設定
這個筆記本討論變數放置。如果您想查看變數放置在什麼裝置上,請取消註解這行。
import tensorflow as tf
# Uncomment to see where your variables get placed (see below)
# tf.debugging.set_log_device_placement(True)
建立變數
若要建立變數,請提供初始值。tf.Variable
將會具有與初始值相同的 dtype
。
my_tensor = tf.constant([[1.0, 2.0], [3.0, 4.0]])
my_variable = tf.Variable(my_tensor)
# Variables can be all kinds of types, just like tensors
bool_variable = tf.Variable([False, False, False, True])
complex_variable = tf.Variable([5 + 4j, 6 + 1j])
變數的外觀和行為都像張量,而且實際上是由 tf.Tensor
支援的資料結構。就像張量一樣,它們具有 dtype
和形狀,而且可以匯出至 NumPy。
print("Shape: ", my_variable.shape)
print("DType: ", my_variable.dtype)
print("As NumPy: ", my_variable.numpy())
大部分的張量運算都可以在變數上如預期般運作,但變數無法重新塑形。
print("A variable:", my_variable)
print("\nViewed as a tensor:", tf.convert_to_tensor(my_variable))
print("\nIndex of highest value:", tf.math.argmax(my_variable))
# This creates a new tensor; it does not reshape the variable.
print("\nCopying and reshaping: ", tf.reshape(my_variable, [1,4]))
如上所述,變數是由張量支援的。您可以使用 tf.Variable.assign
重新指派張量。呼叫 assign
(通常) 不會配置新的張量;而是重複使用現有張量的記憶體。
a = tf.Variable([2.0, 3.0])
# This will keep the same dtype, float32
a.assign([1, 2])
# Not allowed as it resizes the variable:
try:
a.assign([1.0, 2.0, 3.0])
except Exception as e:
print(f"{type(e).__name__}: {e}")
如果您在運算中像張量一樣使用變數,通常會對支援張量執行運算。
從現有變數建立新的變數會複製支援張量。兩個變數不會共用相同的記憶體。
a = tf.Variable([2.0, 3.0])
# Create b based on the value of a
b = tf.Variable(a)
a.assign([5, 6])
# a and b are different
print(a.numpy())
print(b.numpy())
# There are other versions of assign
print(a.assign_add([2,3]).numpy()) # [7. 9.]
print(a.assign_sub([7,9]).numpy()) # [0. 0.]
生命週期、命名和監看
在以 Python 為基礎的 TensorFlow 中,tf.Variable
執行個體具有與其他 Python 物件相同的生命週期。
當沒有對變數的參照時,系統會自動解除配置變數。變數也可以命名,這有助於您追蹤和偵錯變數。您可以為兩個變數指定相同的名稱。
# Create a and b; they will have the same name but will be backed by
# different tensors.
a = tf.Variable(my_tensor, name="Mark")
# A new variable with the same name, but different value
# Note that the scalar add is broadcast
b = tf.Variable(my_tensor + 1, name="Mark")
# These are elementwise-unequal, despite having the same name
print(a == b)
儲存和載入模型時,會保留變數名稱。根據預設,模型中的變數會自動取得唯一的變數名稱,因此除非您想要自行指派,否則不需要指派。
雖然變數對於微分很重要,但有些變數不需要微分。您可以在建立時將 trainable
設定為 false,以關閉變數的梯度。不需要梯度的變數範例是訓練步驟計數器。
step_counter = tf.Variable(1, trainable=False)
放置變數和張量
為了獲得更佳效能,TensorFlow 會嘗試將張量和變數放置在與其 dtype
相容的最快裝置上。這表示如果 GPU 可用,大部分的變數都會放置在 GPU 上。
不過,您可以覆寫此設定。在此程式碼片段中,即使 GPU 可用,仍將浮點張量和變數放置在 CPU 上。透過開啟裝置放置記錄 (請參閱「設定」),您可以查看變數放置在哪裡。
如果您在有無 GPU 的不同後端執行此筆記本,您會看到不同的記錄。請注意,裝置放置記錄必須在工作階段開始時開啟。
with tf.device('CPU:0'):
# Create some tensors
a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
c = tf.matmul(a, b)
print(c)
可以將變數或張量的位置設定在一個裝置上,並在另一個裝置上執行運算。這會造成延遲,因為資料需要在裝置之間複製。
不過,如果您有多個 GPU 工作站,但只想要一份變數副本,您可能會這麼做。
with tf.device('CPU:0'):
a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.Variable([[1.0, 2.0, 3.0]])
with tf.device('GPU:0'):
# Element-wise multiply
k = a * b
print(k)
如需分散式訓練的詳細資訊,請參閱指南。
後續步驟
若要瞭解變數的典型用法,請參閱我們的自動微分指南。