您可以專門爲感興趣的一組變量創建一個tf.Saver
,只要它們具有相同的名稱,就可以在另一個圖中恢復這些變量。你可以使用一個集合來存儲這些變量,然後收集創建保護程序:
TRANSFERABLE_VARIABLES = "transferable_variable"
# ...
my_var = tf.get_variable(...)
tf.add_to_collection(TRANSFERABLE_VARIABLES, my_var)
# ...
saver = tf.Saver(tf.get_collection(TRANSFERABLE_VARIABLES), ...)
這應該允許您撥打save
在一個圖表和restore
在其他轉移的權重。
如果你想避免寫入任何東西到磁盤,那麼我認爲除了手動複製/粘貼值之外別無他法。然而,這也可以通過使用收集和完全相同的施工過程自動化,以公平的程度:
model1_graph = create_model1()
model2_graph = create_model2()
with model1_graph.as_default(), tf.Session() as sess:
# Train...
# Retrieve learned weights
transferable_weights = sess.run(tf.get_collection(TRANSFERABLE_VARIABLES))
with model2_graph.as_default(), tf.Session() as sess:
# Load weights from the other model
for var, weight in zip(tf.get_collection(TRANSFERABLE_VARIABLES),
transferable_weights):
var.load(weight, sess)
# Continue training...
再次,如果公共層的結構是相同的,這將僅工作,因爲順序兩個圖的集合中的變量應該是相同的。
更新:
如果你想確保恢復的變量沒有被用於訓練你有幾個可能性,儘管他們可能都需要在你的代碼更多的變化。 A trainable
變量只是包含在集合tf.GrapKeys.TRAINABLE_VARIABLES
中的一個變量,所以當您在第二個圖中創建傳輸變量時,您可以僅說trainable=False
,並且恢復過程應該工作相同。如果你想變得更具動態性並且自動執行,那麼它或多或少是可能的,但請記住:必須知道必須用於訓練的變量列表創建優化器之前,並且之後不能更改(而不創建新的優化器)。知道這一點,我不認爲有任何解決方案不會通過從第一個圖表中傳遞可傳遞變量名稱的列表。例如。:
with model1_graph.as_default():
transferable_names = [v.name for v in tf.get_collection(TRANSFERABLE_VARIABLES)]
然後,在第二張圖的施工過程中,後的模型定義,只是在創建優化之前,你可以做這樣的事情:
train_vars = [v for v in tf.get_collection(tf.GrapKeys.TRAINABLE_VARIABLES)
if v.name not in transferable_names]
# Assuming that `model2_graph` is the current default graph
tf.get_default_graph().clear_collection(tf.GrapKeys.TRAINABLE_VARIABLES)
for v in train_vars:
tf.add_to_collection(tf.GrapKeys.TRAINABLE_VARIABLES, v)
# Create the optimizer...
另一種選擇是不修改收集tf.GrapKeys.TRAINABLE_VARIABLES
,並將優化器的minimize
方法作爲參數var_list
傳遞給想要優化的變量列表(示例中爲train_vars
)。原則上我個人更喜歡這個,因爲我認爲集合的內容應該符合他們的語義目的(畢竟,代碼的其他部分可能會使用相同的集合用於其他目的),但這取決於我想的情況。
這似乎是我正在尋找。我將專門爲共享變量創建第二個保護程序實例。然後,恢復後,我將加載相應的權重。 – ryuzakinho
我運用了你的方法。重新加載很好。我想知道是否有可能使恢復的變量動態地不可訓練,即只有當我重新加載這些變量時。這樣可以在恢復時不必更改我的代碼。 – ryuzakinho
@ryuzakinho我打算寫回應,但它會太長或很難解釋,所以我已經更新了答案。 – jdehesa