2016-04-12 21 views
2

我想要实现自动编码器(将在精确的堆叠卷积自动编码器)tensorflow复制变量而不是可训练到pretrain下一个层

这里我想pretrain每层的第一和然后微调

所以我创建了各层的权重变量

ex。 W_1 = tf.Variable(initial_value,名称,可训练=真等),用于第一层

和我预训练的第一层的W_1

然后我想pretrain重量第二层的(W_2)

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

但是W_1是可训练的,所以如果我直接使用W_1,张量流可能会训练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) 

但是它会调用错误导致它使用未初始化值

我应该怎么做才能复制变量,但不能将它训练到前面的下一层?

+0

请参阅[输入链接说明](https://stackoverflow.com/questions/37326002/tensorflow-get-variable-change-shared-variable-trainable-to-false) – educob

回答

1

不确定是否仍然相关,但我会尝试。

一般情况下,我在这样的情况做如下:根据您所建立的模型,例如

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

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

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

如何覆盖一个变量的值:name是可变的,以被重写的名称,value是适当的尺寸和类型,sess的阵列会话:

variable = tf.get_default_graph().get_tensor_by_name(name) 
sess.run(tf.assign(variable, value)) 

请注意,name最后还需要额外的:0,所以例如如果图层的权重被称为'weights1',则示例中的name应为​​。

要张量添加到自定义集合:因为它不存在,第二行将给定

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')这将返回您的集合的副本。当然,如果你不想做任何这样的事情,你可以在创建你不希望被训练的所有变量的图时使用trainable=False,正如你在你的问题中暗示的那样。但是,我不太喜欢这个选项,因为它要求你将布尔值传递到填充图的函数中,这很容易被忽略,因此容易出错。另外,即使你决定这样做,你仍然需要手动恢复不可训练的变量。