訓練一個模型時,你需要使用變量來保存和更新權值。變量是在內存緩衝區內的tensor,它們必須被顯式初始化並且可以在模型訓練之後被存儲到硬盤中。接着,你就可以重載被保存的值來練習和分析模型。
本文參考兩個tensorflow類,可以進入下面的鏈接獲取完整的API描述:
創建
- The
tf.Variable
class. - The
tf.train.Saver
class.
當你創建一個變量,你要傳遞一個tensor到Variable()構造器作爲它的初始值。Tensorflow提供了很多用來生成tensor的操作,tensor通常從常量或隨機值來初始化。
注意,這些操作都要求你指定tensor的形狀,指定的形狀會自動的變成變量的大小。變量通常是固定大小的,但tensorflow提供了重塑變量大小的高級機制。
# Create two variables.
weights = tf.Variable(tf.random_normal([784,200], stddev=0.35),name="weights")
biases = tf.Variable(tf.zeros([200]), name="biases")
調用tf.Variable()會在計算圖上添加幾個操作:
- 一個儲存變量值的變量操作
- 一個給變量設置初始值的初始化操作,這通常是一個tf.assign操作
- 對初始值的操作,例如例子中對偏置值的0初始操作就被添加到計算圖中
tf.Variable()返回的結果值是Python類tf.Variable的實例。
指定設備
當一個變量被創建的時候,它可以通過with tf.device(...):塊被分配到指定的設備上:
# Pin a variable to CPU.
with tf.device("/cpu:0"):
v = tf.Variable(...)
# Pin a variable to GPU.
with tf.device("/gpu:0"):
v = tf.Variable(...)
# Pin a variable to a particular parameter server task.
with tf.device("/job:ps/task:7"):
v = tf.Variable(...)
注意:能改變變量的操作,例如tf.Variable.assign以及參數更新操作tf.train.Optimizer必須與變量運行在同一個設備上。不兼容的變量存放指令會在創建時就被忽略掉。指定設備在運行於重複設置時顯得特別重要。用於簡化設備配置的函數細節詳見
tf.train.replica_device_setter
。初始化
參數初始化必須顯式的先於模型其他操作運行。最簡單的方式是添加一個初始化所有參數的操作,然後在訓練模型之前運行這個操作。
你也可以通過重載checkpoint文件以獲得變量值。
使用tf.global_variables_initializer()可以添加一個操作來運行初始化器。在完整構造模型後運行這個初始化器,接着就可以在會話(Session)中開始訓練你的模型。
# Create two variables.
weights = tf.Variable(tf.random_normal([784,200], stddev=0.35), name="weights")
biases = tf.Variable(tf.zeros([200]), name="biases")
...
# Add an op to initialize the variables.
init_op = tf.global_variables_initializer()
# Later, when launching the model
with tf.Session()as sess: # Run the init operation.
sess.run(init_op)
...
# Use the model
...
基於其他變量初始化
有時候你需要利用其他參數的初始值來初始化一個變量。當初始化被tf.global_variables_initializer()操作添加且並行地執行所有變量的初始化時,你必須格外小心。
從另一個變量值初始化一個新變量需要使用其他變量的initialized_value()方法。你可以直接使用(其他變量的)初始值作爲新變量,或者你可以使用它作爲其他tensor來計算一個新變量的值。
# Create a variable with a random value.
weights = tf.Variable(tf.random_normal([784,200], stddev=0.35), name="weights")
# Create another variable with the same value as 'weights'.
w2 = tf.Variable(weights.initialized_value(), name="w2")
# Create another variable with twice the value of 'weights'
w_twice = tf.Variable(weights.initialized_value()*2.0, name="w_twice")
常規初始化
tf.global_variables_initializer()這一便捷的函數添加一個操作來初始化模型中的所有變量。你也可以顯式地傳遞一列變量來使用tf.variables_initializer進行初始。瀏覽關於變量的文檔來獲取更多的選項,包括檢查你的變量是否已經被初始化
保存和重載一個模型最簡單的方法是使用一個
tf.train.Saver
對象。構造器會對所有或部分指定的變量添加save和restore操作到計算圖上。saver對象提供方法來運行這些操作,可以指定checkpoint文件的路徑進行寫出或讀取。
注意,要重載一個模型的checkpoint而不附帶計算圖的話,必須首先從元計算圖文件(通常擴展名是.meta)加載一個計算圖。這樣的操作可以通過tf.train.import_meta_graph實現,這個方法會返回一個能用來重載的Saver對象。
Checkpoint文件
保存變量
選擇所需保存和重載的變量
變量會被存儲於一個二進制文件中,這個文件會包含從變量名到tensor值的映射。當你創建一個Saver對象的時候,你可以在checkpoint文件中爲變量選擇名稱。默認每個變量名會使用tf.Variable.name屬性值。爲了搞明白什麼變量在checkpoint中,你可以使用inspect_checkpoint庫的print_tensors_in_checkpoint_file函數。
通過tf.train.Saver()創建一個Saver來管理模型中的所有變量。
# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add an op to initialize the variables.
init_op = tf.global_variables_initializer()
# Add ops to save and restore all the variables.
saver = tf.train.Saver()
# Later, launch the model, initialize the variables, do some work, save the
# variables to disk.
with tf.Session()as sess:
sess.run(init_op)
# Do some work with the model.
...
# Save the variables to disk.
save_path = saver.save(sess,"/tmp/model.ckpt")
print("Model saved in file: %s"% save_path)
重載變量
Saver對象同樣可以用來重載變量。注意當你從一個文件中重載變量時,你不一定要事先初始化它們。
# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add ops to save and restore all the variables.
saver = tf.train.Saver()
# Later, launch the model, use the saver to restore variables from disk, and
# do some work with the model.
with tf.Session()as sess:
# Restore variables from disk.
saver.restore(sess,"/tmp/model.ckpt")
print("Model restored.")
# Do some work with the model
...
如果你不傳遞任何參數到tf.train.Saver()中的話,saver會處理計算圖中的所有變量。每個變量會被保存在它被創建時所指定的名稱下。
有時在checkpoint文件中爲變量顯式指定名稱是很有用的。例如你可能已經訓練好一個擁有名叫“weights”的變量的模型,可以重載這個變量值到一個名叫“params”的新變量中。
另外,只保存模型中變量的一個子集有時也是很有用的。例如你可能已經訓練好一個5層的神經網絡,而你現在想要訓練一個6層的新模型,可以從先前訓練的模型中重載5層參數到新模型的前5層。
你可以通過傳遞一個以名稱爲key且以變量爲value的Python字典到tf.train.Saver()構造器中進行簡易地存儲。
注意:
- 你可以根據你的需要創建任意多的saver來保存和重載模型變量的不同子集。相同的變量可以被指定到多個saver對象中,它的值只會在saver的restore()方法運行的時候被改變。
- 如果你在會話開始只重載模型變量的一個子集,你必須對其他變量進行一個初始化操作。更多信息請見
tf.variables_initializer
。
# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add ops to save and restore only 'v2' using the name "my_v2"
saver = tf.train.Saver({"my_v2": v2})
# Use the saver object normally after that
....