tensorflow复制变量但不能训练以预先跟踪下一层

时间:2016-04-12 00:08:51

标签: python tensorflow autoencoder

我想实现自动编码器(准确堆叠卷积自动编码器)

这里我想首先预先跟踪每一层,然后进行微调

所以我为每一层的重量创建了变量

离。第一层的W_1 = tf.Variable(initial_value,name,trainable = True等)

我预先训练了第一层的W_1

然后我想预先训练第二层的重量(W_2)

这里我应该用W_1来计算第二层的输入。

然而,W_1是可训练的,所以如果我直接使用W_1,那么tensorflow可以一起训练W_1。

所以我应该创建W_1_out,保持W_1的值,但不能训练

说实话,我试图修改这个网站的代码

https://github.com/cmgreen210/TensorFlowDeepAutoencoder/blob/master/code/ae/autoencoder.py

在第102行,它通过以下代码

创建变量
self[name_w + "_fixed"] = tf.Variable(tf.identity(self[name_w]),
                                            name=name_w + "_fixed",
                                            trainable=False)

然而,它调用错误导致它使用未初始化的值

我该怎样做才能复制变量但是不能训练它来预先训练下一层?

1 个答案:

答案 0 :(得分:2)

不确定是否仍然相关,但无论如何我都会尝试。

一般来说,我在这种情况下所做的事情如下:

  • 根据您正在构建的模型填充(默认)图表,例如对于第一个训练步骤,只需创建您提到的第一个卷积层W1。训练第一层时,您可以在训练完成后存储已保存的模型,然后重新加载它并添加第二层W2所需的操作。或者,您可以直接在代码中从头开始构建W1的整个图表,然后添加W2的操作。

  • 如果您使用Tensorflow提供的恢复机制,您将获得W1的权重已经是预先训练的权重的优势。如果您不使用恢复机制,则必须手动设置W1权重,例如通过执行下面的代码段中显示的内容。

  • 然后,当您设置训练操作时,可以将变量列表作为var_list传递给优化器,优化器会明确告知优化器哪些参数已更新,以便最大限度地减少损失。如果将其设置为None(默认值),则只会使用tf.trainable_variables()中可以找到的内容,而后者则是可训练的所有tf.Variables的集合。也可以检查这个answer,基本上也是这样说的。
  • 使用var_list参数时,图表集合会派上用场。例如。您可以为要训练的每个图层创建单独的图表集合。该集合将包含每个图层的可训练变量,然后您可以非常轻松地检索所需的集合并将其作为var_list参数传递(请参阅下面的示例和/或上述链接文档中的注释)。

如何覆盖变量的值: name是要覆盖的变量的名称,value是具有适当大小和类型的数组{ {1}}是会话:

sess

请注意,variable = tf.get_default_graph().get_tensor_by_name(name) sess.run(tf.assign(variable, value)) 最后需要额外的name,例如如果您的图层权重被调用:0,则示例中的'weights1'应为name

向自定义集合添加张量:使用以下行中的内容:

'weights1:0'

请注意,第一行创建了集合,因为它尚不存在,第二行将给定的张量添加到现有集合中。

如何使用自定义集合:现在您可以执行以下操作:

tf.add_to_collection('layer1_tensors', weights1)
tf.add_to_collection('layer1_tensors', some_other_trainable_variable)

您还可以使用# loss = some tensorflow op computing the loss var_list = tf.get_collection_ref('layer1_tensors') optim = tf.train.AdamOptimizer().minimize(loss=loss, var_list=var_list) 来返回该集合的副本。

当然,如果您不想做其中的任何一项,那么您可以在为所有您想要训练的变量创建图表时使用tf.get_collection('layer_tensors')。你的问题。但是,我不太喜欢这个选项,因为它要求你将布尔值传递给填充图表的函数,这很容易被忽视,因此容易出错。此外,即使你决定这样,你仍然需要手动恢复不可训练的变量。