Tensorflow:使用在一个模型中训练的权重在另一个模型中,使用不同的模型

时间:2016-08-21 20:45:53

标签: python tensorflow lstm

我正在尝试使用miniatches在Tensorflow中训练LSTM,但是在训练完成后我想通过一次提交一个示例来使用该模型。我可以在Tensorflow中设置图形来训练我的LSTM网络,但是我不能以我想要的方式使用训练后的结果。

设置代码如下所示:

#Build the LSTM model.
cellRaw = rnn_cell.BasicLSTMCell(LAYER_SIZE)
cellRaw = rnn_cell.MultiRNNCell([cellRaw] * NUM_LAYERS)

cell = rnn_cell.DropoutWrapper(cellRaw, output_keep_prob = 0.25)

input_data  = tf.placeholder(dtype=tf.float32, shape=[SEQ_LENGTH, None, 3])
target_data = tf.placeholder(dtype=tf.float32, shape=[SEQ_LENGTH, None])
initial_state = cell.zero_state(batch_size=BATCH_SIZE, dtype=tf.float32)

with tf.variable_scope('rnnlm'):
    output_w = tf.get_variable("output_w", [LAYER_SIZE, 6])
    output_b = tf.get_variable("output_b", [6])

outputs, final_state = seq2seq.rnn_decoder(input_list, initial_state, cell, loop_function=None, scope='rnnlm')
output = tf.reshape(tf.concat(1, outputs), [-1, LAYER_SIZE])
output = tf.nn.xw_plus_b(output, output_w, output_b)

...注意两个占位符,input_data和target_data。我没有打扰包括优化器设置。培训结束并且培训课程结束后,我想建立一个使用经过培训的LSTM网络的新会话,该网络的输入由完全不同的占位符提供,如:

with tf.Session() as sess:
with tf.variable_scope("simulation", reuse=None):
    cellSim = cellRaw
    input_data_sim  = tf.placeholder(dtype=tf.float32, shape=[1, 1, 3])
    initial_state_sim = cell.zero_state(batch_size=1, dtype=tf.float32)
    input_list_sim = tf.unpack(input_data_sim)

    outputsSim, final_state_sim = seq2seq.rnn_decoder(input_list_sim, initial_state_sim, cellSim, loop_function=None, scope='rnnlm')
    outputSim = tf.reshape(tf.concat(1, outputsSim), [-1, LAYER_SIZE])

    with tf.variable_scope('rnnlm'):
        output_w = tf.get_variable("output_w", [LAYER_SIZE, nOut])
        output_b = tf.get_variable("output_b", [nOut])

    outputSim = tf.nn.xw_plus_b(outputSim, output_w, output_b)

第二部分返回以下错误:

tensorflow.python.framework.errors.InvalidArgumentError: You must feed a value for placeholder tensor 'Placeholder' with dtype float
 [[Node: Placeholder = Placeholder[dtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/cpu:0"]()]]

...大概是因为我正在使用的图表仍然将旧的训练占位符附加到训练有素的LSTM节点上。什么是“提取”经过训练的LSTM并将其放入具有不同输入风格的新的不同图形的正确方法? Tensorflow似乎解决了类似这样的变量范围功能,但示例in the documentation都讨论了使用变量范围作为管理变量名称的方法,以便同一段代码将在同一个图形中生成类似的子图。 “重用”功能似乎接近我想要的,但我没有发现上面链接的Tensorflow文档完全清楚它的作用。细胞本身不能给出名称(换句话说,

cellRaw = rnn_cell.MultiRNNCell([cellRaw] * NUM_LAYERS, name="multicell")

无效),虽然我可以为seq2seq.rnn_decoder()命名,但如果我使用该节点不变,我可能无法删除rnn_cell.DropoutWrapper()。

问题:

将经过训练的LSTM权重从一个图移动到另一个图的正确方法是什么?

说开始新会话“释放资源”是否正确,但是不会删除内存中的图形?

在我看来,'重用'功能允许Tensorflow在当前变量范围之外搜索具有相同名称的变量(存在于不同的范围内),并在当前范围内使用它们。它是否正确?如果是,那么链接到该变量的非当前范围的所有图形边缘会发生什么?如果不是,如果您尝试在两个不同的范围内使用相同的变量名称,为什么Tensorflow会抛出错误?在两个不同的范围中定义具有相同名称的两个变量似乎是完全合理的,例如conv1 / sum1和conv2 / sum1。

在我的代码中,我正在一个新的范围内工作,但是如果没有数据从初始的默认范围输入占位符,图表将无法运行。由于某种原因,默认范围是否始终是“范围内”?

如果图形边缘可以跨越不同的范围,并且除非它们引用完全相同的节点,否则不能共享不同范围中的名称,那么这似乎首先会破坏具有不同范围的目的。我在这里误解了什么?

谢谢!

1 个答案:

答案 0 :(得分:2)

将训练好的LSTM权重从一个图移动到另一个图的正确方法是什么?

您可以先创建解码图(使用保存对象保存参数)并创建一个GraphDef对象,您可以在更大的训练图中导入该对象:

basegraph = tf.Graph()
with basegraph.as_default():
   ***your graph***

traingraph = tf.Graph()
with traingraph.as_default():
     tf.import_graph_def(basegraph.as_graph_def())
     ***your training graph***

确保在启动新图表的会话时加载变量。

我没有使用此功能的经验,因此您可能需要进一步研究

说开始新会话“释放资源”是否正确,但是不会删除内存中的图表?

是的,图形对象仍然保留它

在我看来,'重用'功能允许Tensorflow在当前变量范围之外搜索具有相同名称的变量(存在于不同的范围内),并在当前范围内使用它们。它是否正确?如果是,那么链接到该变量的非当前范围的所有图形边缘会发生什么?如果不是,如果您尝试在两个不同的范围内使用相同的变量名称,为什么Tensorflow会抛出错误?在两个不同的范围中定义具有相同名称的两个变量似乎是完全合理的,例如conv1 / sum1和conv2 / sum1。

不,重用是确定在现有名称上使用get_variable时的行为,当它为true时它将返回现有变量,否则它将返回一个新变量。通常,tensorflow不应该抛出错误。你确定你使用tf.get_variable而不仅仅是tf.Variable?

在我的代码中,我正在新的范围内工作,但如果没有数据从初始的默认范围输入占位符,图表将无法运行。由于某种原因,默认范围是否始终是“范围内”?

我真的不明白你的意思。并不总是必须使用。如果运行操作不需要占位符,则无需定义它。

如果图形边缘可以跨越不同的范围,并且除非它们引用完全相同的节点,否则不能共享不同范围中的名称,那么这似乎就会破坏首先使用不同范围的目的。我在这里误解了什么?

我认为您对范围的理解或使用存在缺陷,请参阅上文