您可以专门为感兴趣的一组变量创建一个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